[llvm-branch-commits] [cfe-branch] r153047 [1/2] - in /cfe/branches/tooling: ./ bindings/python/clang/ bindings/python/tests/cindex/ docs/ examples/wpa/ include/clang/AST/ include/clang/Analysis/ include/clang/Analysis/Analyses/ include/clang/Analysis/DomainSpecific/ include/clang/Basic/ include/clang/Driver/ include/clang/Edit/ include/clang/Frontend/ include/clang/Index/ include/clang/Lex/ include/clang/Parse/ include/clang/Sema/ include/clang/Serialization/ include/clang/StaticAnalyzer/Core/ include/clang/StaticAnalyzer/Co...
Manuel Klimek
klimek at google.com
Mon Mar 19 12:02:22 PDT 2012
Author: klimek
Date: Mon Mar 19 14:02:20 2012
New Revision: 153047
URL: http://llvm.org/viewvc/llvm-project?rev=153047&view=rev
Log:
Merging mainline.
Added:
cfe/branches/tooling/bindings/python/tests/cindex/util.py
- copied unchanged from r153042, cfe/trunk/bindings/python/tests/cindex/util.py
cfe/branches/tooling/test/CXX/dcl.decl/dcl.meaning/p1.cpp
- copied unchanged from r153042, cfe/trunk/test/CXX/dcl.decl/dcl.meaning/p1.cpp
cfe/branches/tooling/test/CXX/expr/expr.unary/expr.new/p17-crash.cpp
- copied unchanged from r153042, cfe/trunk/test/CXX/expr/expr.unary/expr.new/p17-crash.cpp
cfe/branches/tooling/test/CXX/expr/expr.unary/expr.new/p17.cpp
- copied unchanged from r153042, cfe/trunk/test/CXX/expr/expr.unary/expr.new/p17.cpp
cfe/branches/tooling/test/CXX/lex/lex.charset/p2-cxx11.cpp
- copied unchanged from r153042, cfe/trunk/test/CXX/lex/lex.charset/p2-cxx11.cpp
cfe/branches/tooling/test/CXX/lex/lex.charset/p2-cxx98.cpp
- copied unchanged from r153042, cfe/trunk/test/CXX/lex/lex.charset/p2-cxx98.cpp
cfe/branches/tooling/test/CXX/lex/lex.literal/lex.ext/p2.cpp
- copied unchanged from r153042, cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p2.cpp
cfe/branches/tooling/test/CXX/lex/lex.literal/lex.ext/p3.cpp
- copied unchanged from r153042, cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p3.cpp
cfe/branches/tooling/test/CXX/lex/lex.literal/lex.ext/p4.cpp
- copied unchanged from r153042, cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p4.cpp
cfe/branches/tooling/test/CXX/lex/lex.literal/lex.ext/p5.cpp
- copied unchanged from r153042, cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p5.cpp
cfe/branches/tooling/test/CXX/lex/lex.literal/lex.ext/p6.cpp
- copied unchanged from r153042, cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p6.cpp
cfe/branches/tooling/test/CXX/lex/lex.literal/lex.ext/p7.cpp
- copied unchanged from r153042, cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p7.cpp
cfe/branches/tooling/test/CXX/temp/temp.param/p5.cpp
- copied unchanged from r153042, cfe/trunk/test/CXX/temp/temp.param/p5.cpp
cfe/branches/tooling/test/CXX/temp/temp.spec/temp.inst/p1.cpp
- copied unchanged from r153042, cfe/trunk/test/CXX/temp/temp.spec/temp.inst/p1.cpp
cfe/branches/tooling/test/CodeGen/arm-aapcs-zerolength-bitfield.c
- copied unchanged from r153042, cfe/trunk/test/CodeGen/arm-aapcs-zerolength-bitfield.c
cfe/branches/tooling/test/CodeGen/powerpc_types.c
- copied unchanged from r153042, cfe/trunk/test/CodeGen/powerpc_types.c
cfe/branches/tooling/test/CodeGen/vld_dup.c
- copied unchanged from r153042, cfe/trunk/test/CodeGen/vld_dup.c
cfe/branches/tooling/test/CodeGenCXX/2012-03-16-StoreAlign.cpp
- copied unchanged from r153042, cfe/trunk/test/CodeGenCXX/2012-03-16-StoreAlign.cpp
cfe/branches/tooling/test/CodeGenCXX/blocks-cxx11.cpp
- copied unchanged from r153042, cfe/trunk/test/CodeGenCXX/blocks-cxx11.cpp
cfe/branches/tooling/test/CodeGenCXX/debug-info-template-member.cpp
- copied unchanged from r153042, cfe/trunk/test/CodeGenCXX/debug-info-template-member.cpp
cfe/branches/tooling/test/CodeGenCXX/inheriting-constructor.cpp
- copied unchanged from r153042, cfe/trunk/test/CodeGenCXX/inheriting-constructor.cpp
cfe/branches/tooling/test/Driver/altivec.cpp
- copied unchanged from r153042, cfe/trunk/test/Driver/altivec.cpp
cfe/branches/tooling/test/Driver/diagnostics.c
- copied unchanged from r153042, cfe/trunk/test/Driver/diagnostics.c
cfe/branches/tooling/test/Driver/linker-opts.c
- copied unchanged from r153042, cfe/trunk/test/Driver/linker-opts.c
cfe/branches/tooling/test/FixIt/fixit-vexing-parse-cxx0x.cpp
- copied unchanged from r153042, cfe/trunk/test/FixIt/fixit-vexing-parse-cxx0x.cpp
cfe/branches/tooling/test/Index/index-invalid-code.m
- copied unchanged from r153042, cfe/trunk/test/Index/index-invalid-code.m
cfe/branches/tooling/test/Index/index-many-logical-ops.c
- copied unchanged from r153042, cfe/trunk/test/Index/index-many-logical-ops.c
cfe/branches/tooling/test/Index/pch-with-errors.m
- copied unchanged from r153042, cfe/trunk/test/Index/pch-with-errors.m
cfe/branches/tooling/test/PCH/cxx11-enum-template.cpp
- copied unchanged from r153042, cfe/trunk/test/PCH/cxx11-enum-template.cpp
cfe/branches/tooling/test/Parser/cxx11-type-specifier.cpp
- copied unchanged from r153042, cfe/trunk/test/Parser/cxx11-type-specifier.cpp
cfe/branches/tooling/test/Preprocessor/microsoft-import.c
- copied unchanged from r153042, cfe/trunk/test/Preprocessor/microsoft-import.c
cfe/branches/tooling/test/Rewriter/rewrite-modern-catch.m
- copied unchanged from r153042, cfe/trunk/test/Rewriter/rewrite-modern-catch.m
cfe/branches/tooling/test/Rewriter/rewrite-modern-ivars-2.mm
- copied unchanged from r153042, cfe/trunk/test/Rewriter/rewrite-modern-ivars-2.mm
cfe/branches/tooling/test/Rewriter/rewrite-modern-synchronized.m
- copied unchanged from r153042, cfe/trunk/test/Rewriter/rewrite-modern-synchronized.m
cfe/branches/tooling/test/Rewriter/rewrite-modern-throw.m
- copied unchanged from r153042, cfe/trunk/test/Rewriter/rewrite-modern-throw.m
cfe/branches/tooling/test/Rewriter/rewrite-modern-try-catch-finally.m
- copied unchanged from r153042, cfe/trunk/test/Rewriter/rewrite-modern-try-catch-finally.m
cfe/branches/tooling/test/Rewriter/rewrite-modern-try-finally.m
- copied unchanged from r153042, cfe/trunk/test/Rewriter/rewrite-modern-try-finally.m
cfe/branches/tooling/test/Sema/format-strings-non-iso.c
- copied unchanged from r153042, cfe/trunk/test/Sema/format-strings-non-iso.c
cfe/branches/tooling/test/Sema/many-logical-ops.c
- copied unchanged from r153042, cfe/trunk/test/Sema/many-logical-ops.c
cfe/branches/tooling/test/SemaCXX/PR10447.cpp
- copied unchanged from r153042, cfe/trunk/test/SemaCXX/PR10447.cpp
cfe/branches/tooling/test/SemaCXX/PR8385.cpp
- copied unchanged from r153042, cfe/trunk/test/SemaCXX/PR8385.cpp
cfe/branches/tooling/test/SemaCXX/vla.cpp
- copied unchanged from r153042, cfe/trunk/test/SemaCXX/vla.cpp
cfe/branches/tooling/test/SemaObjC/arc-invalid.m
- copied unchanged from r153042, cfe/trunk/test/SemaObjC/arc-invalid.m
Removed:
cfe/branches/tooling/examples/wpa/
cfe/branches/tooling/lib/StaticAnalyzer/Core/AggExprVisitor.cpp
cfe/branches/tooling/test/CodeGen/va_list_test.c
cfe/branches/tooling/test/Sema/format-strings-non-standard.c
Modified:
cfe/branches/tooling/ (props changed)
cfe/branches/tooling/bindings/python/clang/cindex.py
cfe/branches/tooling/bindings/python/tests/cindex/test_cursor.py
cfe/branches/tooling/bindings/python/tests/cindex/test_diagnostics.py
cfe/branches/tooling/bindings/python/tests/cindex/test_location.py
cfe/branches/tooling/bindings/python/tests/cindex/test_type.py
cfe/branches/tooling/docs/AddressSanitizer.html
cfe/branches/tooling/docs/LanguageExtensions.html
cfe/branches/tooling/docs/ReleaseNotes.html
cfe/branches/tooling/include/clang/AST/APValue.h
cfe/branches/tooling/include/clang/AST/ASTContext.h
cfe/branches/tooling/include/clang/AST/Decl.h
cfe/branches/tooling/include/clang/AST/DeclBase.h
cfe/branches/tooling/include/clang/AST/DeclCXX.h
cfe/branches/tooling/include/clang/AST/DeclFriend.h
cfe/branches/tooling/include/clang/AST/DeclObjC.h
cfe/branches/tooling/include/clang/AST/DeclTemplate.h
cfe/branches/tooling/include/clang/AST/DeclarationName.h
cfe/branches/tooling/include/clang/AST/DependentDiagnostic.h
cfe/branches/tooling/include/clang/AST/Expr.h
cfe/branches/tooling/include/clang/AST/ExprCXX.h
cfe/branches/tooling/include/clang/AST/ExprObjC.h
cfe/branches/tooling/include/clang/AST/NestedNameSpecifier.h
cfe/branches/tooling/include/clang/AST/RecursiveASTVisitor.h
cfe/branches/tooling/include/clang/AST/Stmt.h
cfe/branches/tooling/include/clang/AST/StmtCXX.h
cfe/branches/tooling/include/clang/AST/StmtObjC.h
cfe/branches/tooling/include/clang/AST/TemplateBase.h
cfe/branches/tooling/include/clang/AST/Type.h
cfe/branches/tooling/include/clang/AST/TypeLoc.h
cfe/branches/tooling/include/clang/Analysis/Analyses/FormatString.h
cfe/branches/tooling/include/clang/Analysis/CallGraph.h
cfe/branches/tooling/include/clang/Analysis/DomainSpecific/CocoaConventions.h
cfe/branches/tooling/include/clang/Basic/Builtins.def
cfe/branches/tooling/include/clang/Basic/ConvertUTF.h
cfe/branches/tooling/include/clang/Basic/Diagnostic.h
cfe/branches/tooling/include/clang/Basic/DiagnosticASTKinds.td
cfe/branches/tooling/include/clang/Basic/DiagnosticCommonKinds.td
cfe/branches/tooling/include/clang/Basic/DiagnosticGroups.td
cfe/branches/tooling/include/clang/Basic/DiagnosticLexKinds.td
cfe/branches/tooling/include/clang/Basic/DiagnosticParseKinds.td
cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td
cfe/branches/tooling/include/clang/Basic/LangOptions.def
cfe/branches/tooling/include/clang/Basic/Linkage.h
cfe/branches/tooling/include/clang/Basic/Makefile
cfe/branches/tooling/include/clang/Basic/StmtNodes.td
cfe/branches/tooling/include/clang/Driver/ArgList.h
cfe/branches/tooling/include/clang/Driver/CC1Options.td
cfe/branches/tooling/include/clang/Driver/Options.td
cfe/branches/tooling/include/clang/Edit/EditedSource.h
cfe/branches/tooling/include/clang/Frontend/Analyses.def
cfe/branches/tooling/include/clang/Frontend/AnalyzerOptions.h
cfe/branches/tooling/include/clang/Frontend/CodeGenOptions.h
cfe/branches/tooling/include/clang/Frontend/CompilerInvocation.h
cfe/branches/tooling/include/clang/Index/ASTLocation.h
cfe/branches/tooling/include/clang/Lex/Lexer.h
cfe/branches/tooling/include/clang/Lex/PreprocessingRecord.h
cfe/branches/tooling/include/clang/Lex/Preprocessor.h
cfe/branches/tooling/include/clang/Parse/Parser.h
cfe/branches/tooling/include/clang/Sema/DeclSpec.h
cfe/branches/tooling/include/clang/Sema/Initialization.h
cfe/branches/tooling/include/clang/Sema/Lookup.h
cfe/branches/tooling/include/clang/Sema/Sema.h
cfe/branches/tooling/include/clang/Sema/Template.h
cfe/branches/tooling/include/clang/Serialization/ASTBitCodes.h
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/CheckerManager.h
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h
cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
cfe/branches/tooling/lib/ARCMigrate/ARCMT.cpp
cfe/branches/tooling/lib/ARCMigrate/ObjCMT.cpp
cfe/branches/tooling/lib/ARCMigrate/TransAutoreleasePool.cpp
cfe/branches/tooling/lib/ARCMigrate/TransBlockObjCVariable.cpp
cfe/branches/tooling/lib/ARCMigrate/TransGCAttrs.cpp
cfe/branches/tooling/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
cfe/branches/tooling/lib/ARCMigrate/Transforms.cpp
cfe/branches/tooling/lib/AST/APValue.cpp
cfe/branches/tooling/lib/AST/ASTContext.cpp
cfe/branches/tooling/lib/AST/ASTDiagnostic.cpp
cfe/branches/tooling/lib/AST/ASTImporter.cpp
cfe/branches/tooling/lib/AST/Decl.cpp
cfe/branches/tooling/lib/AST/DeclBase.cpp
cfe/branches/tooling/lib/AST/DeclCXX.cpp
cfe/branches/tooling/lib/AST/DeclObjC.cpp
cfe/branches/tooling/lib/AST/DeclTemplate.cpp
cfe/branches/tooling/lib/AST/DeclarationName.cpp
cfe/branches/tooling/lib/AST/Expr.cpp
cfe/branches/tooling/lib/AST/ExprClassification.cpp
cfe/branches/tooling/lib/AST/ExprConstant.cpp
cfe/branches/tooling/lib/AST/ItaniumMangle.cpp
cfe/branches/tooling/lib/AST/MicrosoftMangle.cpp
cfe/branches/tooling/lib/AST/NestedNameSpecifier.cpp
cfe/branches/tooling/lib/AST/RecordLayoutBuilder.cpp
cfe/branches/tooling/lib/AST/Stmt.cpp
cfe/branches/tooling/lib/AST/StmtDumper.cpp
cfe/branches/tooling/lib/AST/StmtPrinter.cpp
cfe/branches/tooling/lib/AST/StmtProfile.cpp
cfe/branches/tooling/lib/AST/Type.cpp
cfe/branches/tooling/lib/AST/VTableBuilder.cpp
cfe/branches/tooling/lib/Analysis/AnalysisDeclContext.cpp
cfe/branches/tooling/lib/Analysis/CFG.cpp
cfe/branches/tooling/lib/Analysis/CallGraph.cpp
cfe/branches/tooling/lib/Analysis/CocoaConventions.cpp
cfe/branches/tooling/lib/Analysis/FormatString.cpp
cfe/branches/tooling/lib/Analysis/PseudoConstantAnalysis.cpp
cfe/branches/tooling/lib/Analysis/ThreadSafety.cpp
cfe/branches/tooling/lib/Basic/ConvertUTF.c
cfe/branches/tooling/lib/Basic/Diagnostic.cpp
cfe/branches/tooling/lib/Basic/IdentifierTable.cpp
cfe/branches/tooling/lib/Basic/Targets.cpp
cfe/branches/tooling/lib/CodeGen/CGBlocks.cpp
cfe/branches/tooling/lib/CodeGen/CGBuiltin.cpp
cfe/branches/tooling/lib/CodeGen/CGCall.cpp
cfe/branches/tooling/lib/CodeGen/CGClass.cpp
cfe/branches/tooling/lib/CodeGen/CGCleanup.cpp
cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp
cfe/branches/tooling/lib/CodeGen/CGDecl.cpp
cfe/branches/tooling/lib/CodeGen/CGDeclCXX.cpp
cfe/branches/tooling/lib/CodeGen/CGException.cpp
cfe/branches/tooling/lib/CodeGen/CGExpr.cpp
cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp
cfe/branches/tooling/lib/CodeGen/CGExprCXX.cpp
cfe/branches/tooling/lib/CodeGen/CGExprComplex.cpp
cfe/branches/tooling/lib/CodeGen/CGExprConstant.cpp
cfe/branches/tooling/lib/CodeGen/CGExprScalar.cpp
cfe/branches/tooling/lib/CodeGen/CGObjC.cpp
cfe/branches/tooling/lib/CodeGen/CGObjCGNU.cpp
cfe/branches/tooling/lib/CodeGen/CGObjCMac.cpp
cfe/branches/tooling/lib/CodeGen/CGObjCRuntime.cpp
cfe/branches/tooling/lib/CodeGen/CGRTTI.cpp
cfe/branches/tooling/lib/CodeGen/CGRecordLayoutBuilder.cpp
cfe/branches/tooling/lib/CodeGen/CGStmt.cpp
cfe/branches/tooling/lib/CodeGen/CGVTables.cpp
cfe/branches/tooling/lib/CodeGen/CodeGenAction.cpp
cfe/branches/tooling/lib/CodeGen/CodeGenFunction.cpp
cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h
cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp
cfe/branches/tooling/lib/CodeGen/CodeGenModule.h
cfe/branches/tooling/lib/CodeGen/CodeGenTypes.cpp
cfe/branches/tooling/lib/CodeGen/ItaniumCXXABI.cpp
cfe/branches/tooling/lib/CodeGen/ModuleBuilder.cpp
cfe/branches/tooling/lib/CodeGen/TargetInfo.cpp
cfe/branches/tooling/lib/Driver/ArgList.cpp
cfe/branches/tooling/lib/Driver/Driver.cpp
cfe/branches/tooling/lib/Driver/ToolChains.cpp
cfe/branches/tooling/lib/Driver/ToolChains.h
cfe/branches/tooling/lib/Driver/Tools.cpp
cfe/branches/tooling/lib/Driver/WindowsToolChain.cpp
cfe/branches/tooling/lib/Edit/Commit.cpp
cfe/branches/tooling/lib/Edit/RewriteObjCFoundationAPI.cpp
cfe/branches/tooling/lib/Frontend/ASTMerge.cpp
cfe/branches/tooling/lib/Frontend/ASTUnit.cpp
cfe/branches/tooling/lib/Frontend/CacheTokens.cpp
cfe/branches/tooling/lib/Frontend/ChainedIncludesSource.cpp
cfe/branches/tooling/lib/Frontend/CompilerInvocation.cpp
cfe/branches/tooling/lib/Frontend/FrontendAction.cpp
cfe/branches/tooling/lib/Frontend/FrontendActions.cpp
cfe/branches/tooling/lib/Frontend/InitHeaderSearch.cpp
cfe/branches/tooling/lib/Frontend/InitPreprocessor.cpp
cfe/branches/tooling/lib/Frontend/PrintPreprocessedOutput.cpp
cfe/branches/tooling/lib/Frontend/VerifyDiagnosticConsumer.cpp
cfe/branches/tooling/lib/Index/ASTLocation.cpp
cfe/branches/tooling/lib/Lex/Lexer.cpp
cfe/branches/tooling/lib/Lex/LiteralSupport.cpp
cfe/branches/tooling/lib/Lex/PPDirectives.cpp
cfe/branches/tooling/lib/Lex/PPExpressions.cpp
cfe/branches/tooling/lib/Lex/PPLexerChange.cpp
cfe/branches/tooling/lib/Lex/PPMacroExpansion.cpp
cfe/branches/tooling/lib/Lex/Pragma.cpp
cfe/branches/tooling/lib/Lex/Preprocessor.cpp
cfe/branches/tooling/lib/Lex/TokenConcatenation.cpp
cfe/branches/tooling/lib/Lex/TokenLexer.cpp
cfe/branches/tooling/lib/Parse/ParseCXXInlineMethods.cpp
cfe/branches/tooling/lib/Parse/ParseDecl.cpp
cfe/branches/tooling/lib/Parse/ParseDeclCXX.cpp
cfe/branches/tooling/lib/Parse/ParseExpr.cpp
cfe/branches/tooling/lib/Parse/ParseExprCXX.cpp
cfe/branches/tooling/lib/Parse/ParseInit.cpp
cfe/branches/tooling/lib/Parse/ParseObjc.cpp
cfe/branches/tooling/lib/Parse/ParsePragma.cpp
cfe/branches/tooling/lib/Parse/ParseStmt.cpp
cfe/branches/tooling/lib/Parse/ParseTemplate.cpp
cfe/branches/tooling/lib/Parse/ParseTentative.cpp
cfe/branches/tooling/lib/Parse/Parser.cpp
cfe/branches/tooling/lib/Rewrite/HTMLPrint.cpp
cfe/branches/tooling/lib/Rewrite/HTMLRewrite.cpp
cfe/branches/tooling/lib/Rewrite/RewriteMacros.cpp
cfe/branches/tooling/lib/Rewrite/RewriteModernObjC.cpp
cfe/branches/tooling/lib/Rewrite/RewriteObjC.cpp
cfe/branches/tooling/lib/Rewrite/RewriteTest.cpp
cfe/branches/tooling/lib/Sema/CodeCompleteConsumer.cpp
cfe/branches/tooling/lib/Sema/DeclSpec.cpp
cfe/branches/tooling/lib/Sema/IdentifierResolver.cpp
cfe/branches/tooling/lib/Sema/JumpDiagnostics.cpp
cfe/branches/tooling/lib/Sema/Sema.cpp
cfe/branches/tooling/lib/Sema/SemaAccess.cpp
cfe/branches/tooling/lib/Sema/SemaAttr.cpp
cfe/branches/tooling/lib/Sema/SemaCXXScopeSpec.cpp
cfe/branches/tooling/lib/Sema/SemaCast.cpp
cfe/branches/tooling/lib/Sema/SemaChecking.cpp
cfe/branches/tooling/lib/Sema/SemaCodeComplete.cpp
cfe/branches/tooling/lib/Sema/SemaDecl.cpp
cfe/branches/tooling/lib/Sema/SemaDeclAttr.cpp
cfe/branches/tooling/lib/Sema/SemaDeclCXX.cpp
cfe/branches/tooling/lib/Sema/SemaDeclObjC.cpp
cfe/branches/tooling/lib/Sema/SemaExceptionSpec.cpp
cfe/branches/tooling/lib/Sema/SemaExpr.cpp
cfe/branches/tooling/lib/Sema/SemaExprCXX.cpp
cfe/branches/tooling/lib/Sema/SemaExprMember.cpp
cfe/branches/tooling/lib/Sema/SemaExprObjC.cpp
cfe/branches/tooling/lib/Sema/SemaFixItUtils.cpp
cfe/branches/tooling/lib/Sema/SemaInit.cpp
cfe/branches/tooling/lib/Sema/SemaLambda.cpp
cfe/branches/tooling/lib/Sema/SemaLookup.cpp
cfe/branches/tooling/lib/Sema/SemaObjCProperty.cpp
cfe/branches/tooling/lib/Sema/SemaOverload.cpp
cfe/branches/tooling/lib/Sema/SemaPseudoObject.cpp
cfe/branches/tooling/lib/Sema/SemaStmt.cpp
cfe/branches/tooling/lib/Sema/SemaTemplate.cpp
cfe/branches/tooling/lib/Sema/SemaTemplateDeduction.cpp
cfe/branches/tooling/lib/Sema/SemaTemplateInstantiate.cpp
cfe/branches/tooling/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/branches/tooling/lib/Sema/SemaTemplateVariadic.cpp
cfe/branches/tooling/lib/Sema/SemaType.cpp
cfe/branches/tooling/lib/Sema/TargetAttributesSema.cpp
cfe/branches/tooling/lib/Sema/TreeTransform.h
cfe/branches/tooling/lib/Serialization/ASTReader.cpp
cfe/branches/tooling/lib/Serialization/ASTReaderDecl.cpp
cfe/branches/tooling/lib/Serialization/ASTReaderStmt.cpp
cfe/branches/tooling/lib/Serialization/ASTWriter.cpp
cfe/branches/tooling/lib/Serialization/ASTWriterDecl.cpp
cfe/branches/tooling/lib/Serialization/ASTWriterStmt.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/AnalysisManager.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/BugReporter.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/CMakeLists.txt
cfe/branches/tooling/lib/StaticAnalyzer/Core/CheckerContext.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/CoreEngine.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineC.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/MemRegion.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/SValBuilder.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Core/SVals.cpp
cfe/branches/tooling/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
cfe/branches/tooling/test/ASTMerge/Inputs/interface2.m
cfe/branches/tooling/test/Analysis/auto-obj-dtors-cfg-output.cpp
cfe/branches/tooling/test/Analysis/default-analyze.m
cfe/branches/tooling/test/Analysis/dtor.cpp
cfe/branches/tooling/test/Analysis/inline-not-supported.c
cfe/branches/tooling/test/Analysis/inline-plist.c
cfe/branches/tooling/test/Analysis/inline-unique-reports.c
cfe/branches/tooling/test/Analysis/inline.c
cfe/branches/tooling/test/Analysis/inline2.c
cfe/branches/tooling/test/Analysis/inline3.c
cfe/branches/tooling/test/Analysis/inline4.c
cfe/branches/tooling/test/Analysis/keychainAPI.m
cfe/branches/tooling/test/Analysis/malloc-interprocedural.c
cfe/branches/tooling/test/Analysis/malloc-plist.c
cfe/branches/tooling/test/Analysis/misc-ps-region-store.cpp
cfe/branches/tooling/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
cfe/branches/tooling/test/Analysis/nullptr.cpp
cfe/branches/tooling/test/Analysis/plist-output-alternate.m
cfe/branches/tooling/test/Analysis/plist-output.m
cfe/branches/tooling/test/Analysis/retain-release-inline.m
cfe/branches/tooling/test/Analysis/retain-release-path-notes.m
cfe/branches/tooling/test/Analysis/retain-release.m
cfe/branches/tooling/test/Analysis/retain-release.mm
cfe/branches/tooling/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp
cfe/branches/tooling/test/CXX/class.access/p4.cpp
cfe/branches/tooling/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp
cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p2.cpp
cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp
cfe/branches/tooling/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp
cfe/branches/tooling/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p9-0x.cpp
cfe/branches/tooling/test/CXX/dcl.decl/dcl.name/p1.cpp
cfe/branches/tooling/test/CXX/lex/lex.literal/lex.ext/p10.cpp
cfe/branches/tooling/test/CXX/over/over.oper/over.literal/p2.cpp
cfe/branches/tooling/test/CXX/over/over.oper/over.literal/p3.cpp
cfe/branches/tooling/test/CXX/over/over.over/p2-resolve-single-template-id.cpp
cfe/branches/tooling/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
cfe/branches/tooling/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p4.cpp
cfe/branches/tooling/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp
cfe/branches/tooling/test/CXX/temp/temp.spec/temp.explicit/p8.cpp
cfe/branches/tooling/test/CodeGen/asm-variable.c
cfe/branches/tooling/test/CodeGen/atomic.c
cfe/branches/tooling/test/CodeGen/complex-indirect.c
cfe/branches/tooling/test/CodeGen/noinline.c
cfe/branches/tooling/test/CodeGen/x86_64-arguments.c
cfe/branches/tooling/test/CodeGenCXX/copy-constructor-elim-2.cpp
cfe/branches/tooling/test/CodeGenCXX/cxx11-user-defined-literal.cpp
cfe/branches/tooling/test/CodeGenCXX/default-arguments.cpp
cfe/branches/tooling/test/CodeGenCXX/static-init.cpp
cfe/branches/tooling/test/CodeGenCXX/visibility.cpp
cfe/branches/tooling/test/Driver/cpath.c
cfe/branches/tooling/test/Driver/no-objc-arr.m
cfe/branches/tooling/test/Driver/noinline.c
cfe/branches/tooling/test/FixIt/fixit-cxx0x.cpp
cfe/branches/tooling/test/FixIt/fixit-vexing-parse.cpp
cfe/branches/tooling/test/Frontend/ir-support-errors.ll
cfe/branches/tooling/test/Index/complete-enums.c
cfe/branches/tooling/test/Index/pch-with-errors.c
cfe/branches/tooling/test/Lexer/cxx0x_raw_string_delim_length.cpp
cfe/branches/tooling/test/Lexer/has_feature_cxx0x.cpp
cfe/branches/tooling/test/Lexer/string-literal-encoding.c
cfe/branches/tooling/test/Misc/serialized-diags.c
cfe/branches/tooling/test/Misc/warning-flags.c
cfe/branches/tooling/test/Modules/namespaces.cpp
cfe/branches/tooling/test/Parser/MicrosoftExtensions.c
cfe/branches/tooling/test/Parser/cxx0x-ambig.cpp
cfe/branches/tooling/test/Parser/cxx0x-decl.cpp
cfe/branches/tooling/test/Parser/cxx0x-lambda-expressions.cpp
cfe/branches/tooling/test/Parser/cxx11-user-defined-literals.cpp
cfe/branches/tooling/test/Preprocessor/predefined-macros.c
cfe/branches/tooling/test/Sema/arm-neon-types.c
cfe/branches/tooling/test/Sema/c89.c
cfe/branches/tooling/test/Sema/format-strings-c90.c
cfe/branches/tooling/test/Sema/format-strings-fixit.c
cfe/branches/tooling/test/Sema/invalid-struct-init.c
cfe/branches/tooling/test/Sema/pragma-pack-2.c
cfe/branches/tooling/test/Sema/ucn-cstring.c
cfe/branches/tooling/test/Sema/vector-assign.c
cfe/branches/tooling/test/Sema/vector-cast.c
cfe/branches/tooling/test/Sema/vector-ops.c
cfe/branches/tooling/test/SemaCXX/PR9460.cpp
cfe/branches/tooling/test/SemaCXX/__null.cpp
cfe/branches/tooling/test/SemaCXX/alias-template.cpp
cfe/branches/tooling/test/SemaCXX/constant-expression-cxx11.cpp
cfe/branches/tooling/test/SemaCXX/conversion.cpp
cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-constructor.cpp
cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-scalars.cpp
cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
cfe/branches/tooling/test/SemaCXX/cxx11-ast-print.cpp
cfe/branches/tooling/test/SemaCXX/cxx11-user-defined-literals.cpp
cfe/branches/tooling/test/SemaCXX/cxx98-compat.cpp
cfe/branches/tooling/test/SemaCXX/default1.cpp
cfe/branches/tooling/test/SemaCXX/enum-scoped.cpp
cfe/branches/tooling/test/SemaCXX/format-strings.cpp
cfe/branches/tooling/test/SemaCXX/friend.cpp
cfe/branches/tooling/test/SemaCXX/invalid-member-expr.cpp
cfe/branches/tooling/test/SemaCXX/lambda-expressions.cpp
cfe/branches/tooling/test/SemaCXX/literal-operators.cpp
cfe/branches/tooling/test/SemaCXX/missing-namespace-qualifier-typo-corrections.cpp
cfe/branches/tooling/test/SemaCXX/nested-name-spec.cpp
cfe/branches/tooling/test/SemaCXX/new-delete.cpp
cfe/branches/tooling/test/SemaCXX/overload-call.cpp
cfe/branches/tooling/test/SemaCXX/warn-unreachable.cpp (props changed)
cfe/branches/tooling/test/SemaCXX/warn-unused-value.cpp
cfe/branches/tooling/test/SemaObjC/debugger-cast-result-to-id.m
cfe/branches/tooling/test/SemaObjC/format-strings-objc.m
cfe/branches/tooling/test/SemaObjC/invalid-code.m
cfe/branches/tooling/test/SemaObjC/property-9.m
cfe/branches/tooling/test/SemaObjCXX/debugger-cast-result-to-id.mm
cfe/branches/tooling/test/SemaObjCXX/properties.mm
cfe/branches/tooling/test/SemaTemplate/deduction-crash.cpp
cfe/branches/tooling/test/SemaTemplate/qualified-id.cpp
cfe/branches/tooling/tools/arcmt-test/arcmt-test.cpp
cfe/branches/tooling/tools/c-arcmt-test/Makefile
cfe/branches/tooling/tools/c-index-test/Makefile
cfe/branches/tooling/tools/c-index-test/c-index-test.c
cfe/branches/tooling/tools/driver/driver.cpp
cfe/branches/tooling/tools/libclang/CIndex.cpp
cfe/branches/tooling/tools/libclang/CIndexCodeCompletion.cpp
cfe/branches/tooling/tools/libclang/CIndexDiagnostic.cpp
cfe/branches/tooling/tools/libclang/CIndexUSRs.cpp
cfe/branches/tooling/tools/libclang/CXCursor.cpp
cfe/branches/tooling/tools/libclang/CXSourceLocation.h
cfe/branches/tooling/utils/FuzzTest
cfe/branches/tooling/utils/clangVisualizers.txt
cfe/branches/tooling/www/analyzer/latest_checker.html.incl
cfe/branches/tooling/www/analyzer/release_notes.html
cfe/branches/tooling/www/cxx_status.html
Propchange: cfe/branches/tooling/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Mar 19 14:02:20 2012
@@ -1,3 +1,3 @@
/cfe/branches/type-system-rewrite:134693-134817
-/cfe/trunk:146581-152324
+/cfe/trunk:146581-153042
/cfe/trunk/test/SemaTemplate:126920
Modified: cfe/branches/tooling/bindings/python/clang/cindex.py
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/bindings/python/clang/cindex.py?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/bindings/python/clang/cindex.py (original)
+++ cfe/branches/tooling/bindings/python/clang/cindex.py Mon Mar 19 14:02:20 2012
@@ -1008,6 +1008,14 @@
return self._enum_type
@property
+ def objc_type_encoding(self):
+ """Return the Objective-C type encoding as a str."""
+ if not hasattr(self, '_objc_type_encoding'):
+ self._objc_type_encoding = Cursor_objc_type_encoding(self)
+
+ return self._objc_type_encoding
+
+ @property
def hash(self):
"""Returns a hash of the cursor as an int."""
if not hasattr(self, '_hash'):
@@ -1920,6 +1928,11 @@
Cursor_enum_type.restype = Type
Cursor_enum_type.errcheck = Type.from_result
+Cursor_objc_type_encoding = lib.clang_getDeclObjCTypeEncoding
+Cursor_objc_type_encoding.argtypes = [Cursor]
+Cursor_objc_type_encoding.restype = _CXString
+Cursor_objc_type_encoding.errcheck = _CXString.from_result
+
Cursor_visit_callback = CFUNCTYPE(c_int, Cursor, Cursor, py_object)
Cursor_visit = lib.clang_visitChildren
Cursor_visit.argtypes = [Cursor, Cursor_visit_callback, py_object]
Modified: cfe/branches/tooling/bindings/python/tests/cindex/test_cursor.py
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/bindings/python/tests/cindex/test_cursor.py?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/bindings/python/tests/cindex/test_cursor.py (original)
+++ cfe/branches/tooling/bindings/python/tests/cindex/test_cursor.py Mon Mar 19 14:02:20 2012
@@ -1,4 +1,7 @@
-from clang.cindex import Index, CursorKind, TypeKind
+from clang.cindex import CursorKind
+from clang.cindex import TypeKind
+from .util import get_cursor
+from .util import get_tu
kInput = """\
// FIXME: Find nicer way to drop builtins and other cruft.
@@ -24,9 +27,8 @@
"""
def test_get_children():
- index = Index.create()
- tu = index.parse('t.c', unsaved_files = [('t.c',kInput)])
-
+ tu = get_tu(kInput)
+
# Skip until past start_decl.
it = tu.cursor.get_children()
while it.next().spelling != 'start_decl':
@@ -65,31 +67,26 @@
assert tu_nodes[2].is_definition() == True
def test_underlying_type():
- source = 'typedef int foo;'
- index = Index.create()
- tu = index.parse('test.c', unsaved_files=[('test.c', source)])
- assert tu is not None
-
- for cursor in tu.cursor.get_children():
- if cursor.spelling == 'foo':
- typedef = cursor
- break
+ tu = get_tu('typedef int foo;')
+ typedef = get_cursor(tu, 'foo')
+ assert typedef is not None
assert typedef.kind.is_declaration()
underlying = typedef.underlying_typedef_type
assert underlying.kind == TypeKind.INT
def test_enum_type():
- source = 'enum TEST { FOO=1, BAR=2 };'
- index = Index.create()
- tu = index.parse('test.c', unsaved_files=[('test.c', source)])
- assert tu is not None
-
- for cursor in tu.cursor.get_children():
- if cursor.spelling == 'TEST':
- enum = cursor
- break
+ tu = get_tu('enum TEST { FOO=1, BAR=2 };')
+ enum = get_cursor(tu, 'TEST')
+ assert enum is not None
assert enum.kind == CursorKind.ENUM_DECL
enum_type = enum.enum_type
assert enum_type.kind == TypeKind.UINT
+
+def test_objc_type_encoding():
+ tu = get_tu('int i;', lang='objc')
+ i = get_cursor(tu, 'i')
+
+ assert i is not None
+ assert i.objc_type_encoding == 'i'
Modified: cfe/branches/tooling/bindings/python/tests/cindex/test_diagnostics.py
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/bindings/python/tests/cindex/test_diagnostics.py?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/bindings/python/tests/cindex/test_diagnostics.py (original)
+++ cfe/branches/tooling/bindings/python/tests/cindex/test_diagnostics.py Mon Mar 19 14:02:20 2012
@@ -1,19 +1,10 @@
from clang.cindex import *
-
-def tu_from_source(source, all_warnings=False):
- args = []
- if all_warnings:
- args = ['-Wall', '-Wextra']
-
- index = Index.create()
- tu = index.parse('INPUT.c', args=args,
- unsaved_files = [('INPUT.c', source)])
- return tu
+from .util import get_tu
# FIXME: We need support for invalid translation units to test better.
def test_diagnostic_warning():
- tu = tu_from_source("""int f0() {}\n""")
+ tu = get_tu('int f0() {}\n')
assert len(tu.diagnostics) == 1
assert tu.diagnostics[0].severity == Diagnostic.Warning
assert tu.diagnostics[0].location.line == 1
@@ -23,8 +14,7 @@
def test_diagnostic_note():
# FIXME: We aren't getting notes here for some reason.
- index = Index.create()
- tu = tu_from_source("""#define A x\nvoid *A = 1;\n""")
+ tu = get_tu('#define A x\nvoid *A = 1;\n')
assert len(tu.diagnostics) == 1
assert tu.diagnostics[0].severity == Diagnostic.Warning
assert tu.diagnostics[0].location.line == 2
@@ -36,8 +26,7 @@
# assert tu.diagnostics[1].spelling == 'instantiated from'
def test_diagnostic_fixit():
- index = Index.create()
- tu = tu_from_source("""struct { int f0; } x = { f0 : 1 };""")
+ tu = get_tu('struct { int f0; } x = { f0 : 1 };')
assert len(tu.diagnostics) == 1
assert tu.diagnostics[0].severity == Diagnostic.Warning
assert tu.diagnostics[0].location.line == 1
@@ -51,8 +40,7 @@
assert tu.diagnostics[0].fixits[0].value == '.f0 = '
def test_diagnostic_range():
- index = Index.create()
- tu = tu_from_source("""void f() { int i = "a" + 1; }""")
+ tu = get_tu('void f() { int i = "a" + 1; }')
assert len(tu.diagnostics) == 1
assert tu.diagnostics[0].severity == Diagnostic.Warning
assert tu.diagnostics[0].location.line == 1
@@ -72,9 +60,8 @@
assert False
def test_diagnostic_category():
- # Ensure that category properties work.
- index = Index.create()
- tu = tu_from_source("""int f(int i) { return 7; }""", all_warnings=True)
+ """Ensure that category properties work."""
+ tu = get_tu('int f(int i) { return 7; }', all_warnings=True)
assert len(tu.diagnostics) == 1
d = tu.diagnostics[0]
@@ -86,12 +73,10 @@
assert d.category_name == 'Semantic Issue'
def test_diagnostic_option():
- # Ensure that category option properties work.
- index = Index.create()
- tu = tu_from_source("""int f(int i) { return 7; }""", all_warnings=True)
+ """Ensure that category option properties work."""
+ tu = get_tu('int f(int i) { return 7; }', all_warnings=True)
assert len(tu.diagnostics) == 1
d = tu.diagnostics[0]
assert d.option == '-Wunused-parameter'
assert d.disable_option == '-Wno-unused-parameter'
-
Modified: cfe/branches/tooling/bindings/python/tests/cindex/test_location.py
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/bindings/python/tests/cindex/test_location.py?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/bindings/python/tests/cindex/test_location.py (original)
+++ cfe/branches/tooling/bindings/python/tests/cindex/test_location.py Mon Mar 19 14:02:20 2012
@@ -1,4 +1,9 @@
-from clang.cindex import Index, File, SourceLocation, SourceRange, Cursor
+from clang.cindex import Cursor
+from clang.cindex import File
+from clang.cindex import SourceLocation
+from clang.cindex import SourceRange
+from .util import get_cursor
+from .util import get_tu
baseInput="int one;\nint two;\n"
@@ -8,44 +13,46 @@
assert loc.offset == offset
def test_location():
- index = Index.create()
- tu = index.parse('t.c', unsaved_files = [('t.c',baseInput)])
+ tu = get_tu(baseInput)
+ one = get_cursor(tu, 'one')
+ two = get_cursor(tu, 'two')
- for n in tu.cursor.get_children():
- if n.spelling == 'one':
- assert_location(n.location,line=1,column=5,offset=4)
- if n.spelling == 'two':
- assert_location(n.location,line=2,column=5,offset=13)
+ assert one is not None
+ assert two is not None
+
+ assert_location(one.location,line=1,column=5,offset=4)
+ assert_location(two.location,line=2,column=5,offset=13)
# adding a linebreak at top should keep columns same
- tu = index.parse('t.c', unsaved_files = [('t.c',"\n"+baseInput)])
+ tu = get_tu('\n' + baseInput)
+ one = get_cursor(tu, 'one')
+ two = get_cursor(tu, 'two')
+
+ assert one is not None
+ assert two is not None
- for n in tu.cursor.get_children():
- if n.spelling == 'one':
- assert_location(n.location,line=2,column=5,offset=5)
- if n.spelling == 'two':
- assert_location(n.location,line=3,column=5,offset=14)
+ assert_location(one.location,line=2,column=5,offset=5)
+ assert_location(two.location,line=3,column=5,offset=14)
# adding a space should affect column on first line only
- tu = index.parse('t.c', unsaved_files = [('t.c'," "+baseInput)])
+ tu = get_tu(' ' + baseInput)
+ one = get_cursor(tu, 'one')
+ two = get_cursor(tu, 'two')
- for n in tu.cursor.get_children():
- if n.spelling == 'one':
- assert_location(n.location,line=1,column=6,offset=5)
- if n.spelling == 'two':
- assert_location(n.location,line=2,column=5,offset=14)
+ assert_location(one.location,line=1,column=6,offset=5)
+ assert_location(two.location,line=2,column=5,offset=14)
# define the expected location ourselves and see if it matches
# the returned location
- tu = index.parse('t.c', unsaved_files = [('t.c',baseInput)])
+ tu = get_tu(baseInput)
file = File.from_name(tu, 't.c')
location = SourceLocation.from_position(tu, file, 1, 5)
cursor = Cursor.from_location(tu, location)
- for n in tu.cursor.get_children():
- if n.spelling == 'one':
- assert n == cursor
+ one = get_cursor(tu, 'one')
+ assert one is not None
+ assert one == cursor
# Ensure locations referring to the same entity are equivalent.
location2 = SourceLocation.from_position(tu, file, 1, 5)
@@ -54,18 +61,17 @@
assert location2 != location3
def test_extent():
- index = Index.create()
- tu = index.parse('t.c', unsaved_files = [('t.c',baseInput)])
-
- for n in tu.cursor.get_children():
- if n.spelling == 'one':
- assert_location(n.extent.start,line=1,column=1,offset=0)
- assert_location(n.extent.end,line=1,column=8,offset=7)
- assert baseInput[n.extent.start.offset:n.extent.end.offset] == "int one"
- if n.spelling == 'two':
- assert_location(n.extent.start,line=2,column=1,offset=9)
- assert_location(n.extent.end,line=2,column=8,offset=16)
- assert baseInput[n.extent.start.offset:n.extent.end.offset] == "int two"
+ tu = get_tu(baseInput)
+ one = get_cursor(tu, 'one')
+ two = get_cursor(tu, 'two')
+
+ assert_location(one.extent.start,line=1,column=1,offset=0)
+ assert_location(one.extent.end,line=1,column=8,offset=7)
+ assert baseInput[one.extent.start.offset:one.extent.end.offset] == "int one"
+
+ assert_location(two.extent.start,line=2,column=1,offset=9)
+ assert_location(two.extent.end,line=2,column=8,offset=16)
+ assert baseInput[two.extent.start.offset:two.extent.end.offset] == "int two"
file = File.from_name(tu, 't.c')
location1 = SourceLocation.from_position(tu, file, 1, 1)
Modified: cfe/branches/tooling/bindings/python/tests/cindex/test_type.py
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/bindings/python/tests/cindex/test_type.py?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/bindings/python/tests/cindex/test_type.py (original)
+++ cfe/branches/tooling/bindings/python/tests/cindex/test_type.py Mon Mar 19 14:02:20 2012
@@ -1,8 +1,9 @@
-from clang.cindex import Cursor
from clang.cindex import CursorKind
from clang.cindex import Index
from clang.cindex import TypeKind
from nose.tools import raises
+from .util import get_cursor
+from .util import get_tu
kInput = """\
@@ -21,35 +22,6 @@
"""
-def get_tu(source=kInput, lang='c'):
- name = 't.c'
- if lang == 'cpp':
- name = 't.cpp'
-
- index = Index.create()
- tu = index.parse(name, unsaved_files=[(name, source)])
- assert tu is not None
- return tu
-
-def get_cursor(source, spelling):
- children = []
- if isinstance(source, Cursor):
- children = source.get_children()
- else:
- # Assume TU
- children = source.cursor.get_children()
-
- for cursor in children:
- if cursor.spelling == spelling:
- return cursor
-
- # Recurse into children.
- result = get_cursor(cursor, spelling)
- if result is not None:
- return result
-
- return None
-
def test_a_struct():
tu = get_tu(kInput)
Modified: cfe/branches/tooling/docs/AddressSanitizer.html
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/docs/AddressSanitizer.html?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/docs/AddressSanitizer.html (original)
+++ cfe/branches/tooling/docs/AddressSanitizer.html Mon Mar 19 14:02:20 2012
@@ -43,7 +43,9 @@
Typical slowdown introduced by AddressSanitizer is <b>2x</b>.
<h2 id="howtobuild">How to build</h2>
-Follow the <a href="../get_started.html">clang build instructions</a>.
+Follow the <a href="../get_started.html">clang build instructions</a>. <BR>
+Note: CMake build does not work yet.
+See <a href="http://llvm.org/bugs/show_bug.cgi?id=12272">bug 12272</a>.
<h2 id="usage">Usage</h2>
Simply compile and link your program with <tt>-faddress-sanitizer</tt> flag. <BR>
@@ -107,7 +109,9 @@
<ul><li>Linux x86_64 (tested on Ubuntu 10.04).
<li>MacOS 10.6 i386/x86_64.
</ul>
-Support for Linux i386/ARM and MacOS 10.7 is in progress.
+Support for Linux i386/ARM and MacOS 10.7 is in progress
+(it may work, but is not guaranteed too).
+
<h2 id="limitations">Limitations</h2>
<ul>
Modified: cfe/branches/tooling/docs/LanguageExtensions.html
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/docs/LanguageExtensions.html?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/docs/LanguageExtensions.html (original)
+++ cfe/branches/tooling/docs/LanguageExtensions.html Mon Mar 19 14:02:20 2012
@@ -30,6 +30,7 @@
<li><a href="#vectors">Vectors and Extended Vectors</a></li>
<li><a href="#deprecated">Messages on <tt>deprecated</tt> and <tt>unavailable</tt> attributes</a></li>
<li><a href="#attributes-on-enumerators">Attributes on enumerators</a></li>
+<li><a href="#availability">Availability attribute</a></li>
<li><a href="#checking_language_features">Checks for Standard Language Features</a>
<ul>
<li><a href="#cxx_exceptions">C++ exceptions</a></li>
@@ -87,6 +88,7 @@
<li><a href="#objc_instancetype">Related result types</a></li>
<li><a href="#objc_arc">Automatic reference counting</a></li>
<li><a href="#objc_fixed_enum">Enumerations with a fixed underlying type</a></li>
+ <li><a href="#objc_lambdas">Interoperability with C++11 lambdas</a></li>
</ul>
</li>
<li><a href="#overloading-in-c">Function Overloading in C</a></li>
@@ -621,6 +623,55 @@
<p>Query for this feature with <tt>__has_extension(enumerator_attributes)</tt>.</p>
<!-- ======================================================================= -->
+<h2 id="availability">Availability attribute</h2
+<!-- ======================================================================= -->
+
+<p>Clang introduces the <code>availability</code> attribute, which can
+be placed on declarations to describe the lifecycle of that
+declaration relative to operating system versions. Consider the function declaration for a hypothetical function <code>f</code>:</p>
+
+<pre>
+void f(void) __attribute__((availability(macosx,introduced=10.4,deprecated=10.6,obsoleted=10.7)));
+</pre>
+
+<p>The availability attribute states that <code>f</code> was introduced in Mac OS X 10.4, deprecated in Mac OS X 10.6, and obsoleted in Mac OS X 10.7. This information is used by Clang to determine when it is safe to use <code>f</code>: for example, if Clang is instructed to compile code for Mac OS X 10.5, a call to <code>f()</code> succeeds. If Clang is instructed to compile code for Mac OS X 10.6, the call succeeds but Clang emits a warning specifying that the function is deprecated. Finally, if Clang is instructed to compile code for Mac OS X 10.7, the call fails because <code>f()</code> is no longer available.</p>
+
+<p>The availablility attribute is a comma-separated list starting with the platform name and then including clauses specifying important milestones in the declaration's lifetime (in any order) along with additional information. Those clauses can be:</p>
+
+<dl>
+ <dt>introduced=<i>version</i></dt>
+ <dd>The first version in which this declaration was introduced.</dd>
+
+ <dt>deprecated=<i>version</i></dt>
+ <dd>The first version in which this declaration was deprecated, meaning that users should migrate away from this API.</dd>
+
+ <dt>obsoleted=<i>version</i></dt>
+ <dd>The first version in which this declaration was obsoleted, meaning that it was removed completely and can no longer be used.</dd>
+
+ <dt>unavailable</dt>
+ <dd>This declaration is never available on this platform.</dd>
+
+ <dt>message=<i>string-literal</i></dt>
+ <dd>Additional message text that Clang will provide when emitting a warning or error about use of a deprecated or obsoleted declaration. Useful to direct users to replacement APIs.</dd>
+</dl>
+
+<p>Multiple availability attributes can be placed on a declaration, which may correspond to different platforms. Only the availability attribute with the platform corresponding to the target platform will be used; any others will be ignored. If no availability attribute specifies availability for the current target platform, the availability attributes are ignored. Supported platforms are:</p>
+
+<dl>
+ <dt>ios</dt>
+ <dd>Apple's iOS operating system. The minimum deployment target is specified by the <code>-mios-version-min=<i>version</i></code> or <code>-miphoneos-version-min=<i>version</i></code> command-line arguments.</dd>
+
+ <dt>macosx</dt>
+ <dd>Apple's Mac OS X operating system. The minimum deployment target is specified by the <code>-mmacosx-version-min=<i>version</i></code> command-line argument.</dd>
+</dl>
+
+<p>A declaration can be used even when deploying back to a platform
+version prior to when the declaration was introduced. When this
+happens, the declaration is <a
+ href="https://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html">weakly
+linked</a>, as if the <code>weak_import</code> attribute were added to the declaration. A weakly-linked declaration may or may not be present a run-time, and a program can determine whether the declaration is present by checking whether the address of that declaration is non-NULL.</p>
+
+<!-- ======================================================================= -->
<h2 id="checking_language_features">Checks for Standard Language Features</h2>
<!-- ======================================================================= -->
@@ -819,7 +870,7 @@
<h4 id="cxx_user_literals">C++11 user-defined literals</h4>
-<p>Use <tt>__has_feature(cxx_user_literals)</tt> to determine if support for user-defined literals is enabled. Clang does not currently support this feature.</p>
+<p>Use <tt>__has_feature(cxx_user_literals)</tt> to determine if support for user-defined literals is enabled.</p>
<h4 id="cxx_variadic_templates">C++11 variadic templates</h4>
@@ -1022,6 +1073,66 @@
support for fixed underlying types is available in Objective-C.</p>
<!-- ======================================================================= -->
+<h2 id="objc_lambdas">Interoperability with C++11 lambdas</h2>
+<!-- ======================================================================= -->
+
+<p>Clang provides interoperability between C++11 lambdas and
+blocks-based APIs, by permitting a lambda to be implicitly converted
+to a block pointer with the corresponding signature. For example,
+consider an API such as <code>NSArray</code>'s array-sorting
+method:</p>
+
+<pre> - (NSArray *)sortedArrayUsingComparator:(NSComparator)cmptr; </pre>
+
+<p><code>NSComparator</code> is simply a typedef for the block pointer
+<code>NSComparisonResult (^)(id, id)</code>, and parameters of this
+type are generally provided with block literals as arguments. However,
+one can also use a C++11 lambda so long as it provides the same
+signature (in this case, accepting two parameters of type
+<code>id</code> and returning an <code>NSComparisonResult</code>):</p>
+
+<pre>
+ NSArray *array = @[@"string 1", @"string 21", @"string 12", @"String 11",
+ @"String 02"];
+ const NSStringCompareOptions comparisonOptions
+ = NSCaseInsensitiveSearch | NSNumericSearch |
+ NSWidthInsensitiveSearch | NSForcedOrderingSearch;
+ NSLocale *currentLocale = [NSLocale currentLocale];
+ NSArray *sorted
+ = [array sortedArrayUsingComparator:<b>[=](id s1, id s2) -> NSComparisonResult {
+ NSRange string1Range = NSMakeRange(0, [s1 length]);
+ return [s1 compare:s2 options:comparisonOptions
+ range:string1Range locale:currentLocale];
+ }</b>];
+ NSLog(@"sorted: %@", sorted);
+</pre>
+
+<p>This code relies on an implicit conversion from the type of the
+lambda expression (an unnamed, local class type called the <i>closure
+type</i>) to the corresponding block pointer type. The conversion
+itself is expressed by a conversion operator in that closure type
+that produces a block pointer with the same signature as the lambda
+itself, e.g.,</p>
+
+<pre>
+ operator NSComparisonResult (^)(id, id)() const;
+</pre>
+
+<p>This conversion function returns a new block that simply forwards
+the two parameters to the lambda object (which it captures by copy),
+then returns the result. The returned block is first copied (with
+<tt>Block_copy</tt>) and then autoreleased. As an optimization, if a
+lambda expression is immediately converted to a block pointer (as in
+the first example, above), then the block is not copied and
+autoreleased: rather, it is given the same lifetime as a block literal
+written at that point in the program, which avoids the overhead of
+copying a block to the heap in the common case.</p>
+
+<p>The conversion from a lambda to a block pointer is only available
+in Objective-C++, and not in C++ with blocks, due to its use of
+Objective-C memory management (autorelease).</p>
+
+<!-- ======================================================================= -->
<h2 id="overloading-in-c">Function Overloading in C</h2>
<!-- ======================================================================= -->
Modified: cfe/branches/tooling/docs/ReleaseNotes.html
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/docs/ReleaseNotes.html?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/docs/ReleaseNotes.html (original)
+++ cfe/branches/tooling/docs/ReleaseNotes.html Mon Mar 19 14:02:20 2012
@@ -124,6 +124,7 @@
<li>Lambda expressions</li>
<li>Generalized initializers</li>
<li>Unrestricted unions</li>
+ <li>User-defined literals</li>
</ul>
<!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
Modified: cfe/branches/tooling/include/clang/AST/APValue.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/APValue.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/APValue.h (original)
+++ cfe/branches/tooling/include/clang/AST/APValue.h Mon Mar 19 14:02:20 2012
@@ -135,9 +135,7 @@
APValue(const APFloat &R, const APFloat &I) : Kind(Uninitialized) {
MakeComplexFloat(); setComplexFloat(R, I);
}
- APValue(const APValue &RHS) : Kind(Uninitialized) {
- *this = RHS;
- }
+ APValue(const APValue &RHS);
APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex)
: Kind(Uninitialized) {
MakeLValue(); setLValue(B, O, N, CallIndex);
@@ -170,6 +168,9 @@
MakeUninit();
}
+ /// \brief Swaps the contents of this and the given APValue.
+ void swap(APValue &RHS);
+
ValueKind getKind() const { return Kind; }
bool isUninit() const { return Kind == Uninitialized; }
bool isInt() const { return Kind == Int; }
@@ -382,10 +383,18 @@
((AddrLabelDiffData*)(char*)Data)->RHSExpr = RHSExpr;
}
- const APValue &operator=(const APValue &RHS);
+ /// Assign by swapping from a copy of the RHS.
+ APValue &operator=(APValue RHS) {
+ swap(RHS);
+ return *this;
+ }
private:
- void MakeUninit();
+ void DestroyDataAndMakeUninit();
+ void MakeUninit() {
+ if (Kind != Uninitialized)
+ DestroyDataAndMakeUninit();
+ }
void MakeInt() {
assert(isUninit() && "Bad state change");
new ((void*)Data) APSInt(1);
Modified: cfe/branches/tooling/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/ASTContext.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/ASTContext.h (original)
+++ cfe/branches/tooling/include/clang/AST/ASTContext.h Mon Mar 19 14:02:20 2012
@@ -147,6 +147,11 @@
mutable llvm::DenseMap<const ObjCContainerDecl*, const ASTRecordLayout*>
ObjCLayouts;
+ /// TypeInfoMap - A cache from types to size and alignment information.
+ typedef llvm::DenseMap<const Type*,
+ std::pair<uint64_t, unsigned> > TypeInfoMap;
+ mutable TypeInfoMap MemoizedTypeInfo;
+
/// KeyFunctions - A cache mapping from CXXRecordDecls to key functions.
llvm::DenseMap<const CXXRecordDecl*, const CXXMethodDecl*> KeyFunctions;
@@ -406,7 +411,7 @@
const TargetInfo &getTargetInfo() const { return *Target; }
- const LangOptions& getLangOptions() const { return LangOpts; }
+ const LangOptions& getLangOpts() const { return LangOpts; }
DiagnosticsEngine &getDiagnostics() const;
@@ -1053,7 +1058,7 @@
/// \brief The result type of logical operations, '<', '>', '!=', etc.
QualType getLogicalOperationType() const {
- return getLangOptions().CPlusPlus ? BoolTy : IntTy;
+ return getLangOpts().CPlusPlus ? BoolTy : IntTy;
}
/// getObjCEncodingForType - Emit the ObjC type encoding for the
@@ -1220,6 +1225,7 @@
private:
CanQualType getFromTargetType(unsigned Type) const;
+ std::pair<uint64_t, unsigned> getTypeInfoImpl(const Type *T) const;
//===--------------------------------------------------------------------===//
// Type Predicates.
Modified: cfe/branches/tooling/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/Decl.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/Decl.h (original)
+++ cfe/branches/tooling/include/clang/AST/Decl.h Mon Mar 19 14:02:20 2012
@@ -22,6 +22,7 @@
#include "clang/Basic/Linkage.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/Support/Compiler.h"
namespace clang {
class CXXTemporary;
@@ -106,6 +107,9 @@
/// constructor, Objective-C selector, etc.)
DeclarationName Name;
+private:
+ NamedDecl *getUnderlyingDeclImpl();
+
protected:
NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
: Decl(DK, DC, L), Name(N) { }
@@ -324,12 +328,13 @@
/// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
/// the underlying named decl.
NamedDecl *getUnderlyingDecl() {
- if (!(this->getKind() == UsingShadow) &&
- !(this->getKind() == ObjCCompatibleAlias))
+ // Fast-path the common case.
+ if (this->getKind() != UsingShadow &&
+ this->getKind() != ObjCCompatibleAlias)
return this;
+
return getUnderlyingDeclImpl();
}
- NamedDecl *getUnderlyingDeclImpl();
const NamedDecl *getUnderlyingDecl() const {
return const_cast<NamedDecl*>(this)->getUnderlyingDecl();
}
@@ -375,7 +380,7 @@
bool isGnuLocal() const { return LocStart != getLocation(); }
void setLocStart(SourceLocation L) { LocStart = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(LocStart, getLocation());
}
@@ -496,11 +501,11 @@
return getOriginalNamespace();
}
- virtual SourceRange getSourceRange() const {
+ virtual SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(LocStart, RBraceLoc);
}
- SourceLocation getLocStart() const { return LocStart; }
+ SourceLocation getLocStart() const LLVM_READONLY { return LocStart; }
SourceLocation getRBraceLoc() const { return RBraceLoc; }
void setLocStart(SourceLocation L) { LocStart = L; }
void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
@@ -628,7 +633,10 @@
/// range taking into account any outer template declarations.
SourceLocation getOuterLocStart() const;
- virtual SourceRange getSourceRange() const;
+ virtual SourceRange getSourceRange() const LLVM_READONLY;
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return getOuterLocStart();
+ }
/// \brief Retrieve the nested-name-specifier that qualifies the name of this
/// declaration, if it was present in the source.
@@ -843,7 +851,7 @@
static VarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- virtual SourceRange getSourceRange() const;
+ virtual SourceRange getSourceRange() const LLVM_READONLY;
StorageClass getStorageClass() const {
return (StorageClass) VarDeclBits.SClass;
@@ -947,11 +955,17 @@
/// \brief Check whether this declaration is a definition. If this could be
/// a tentative definition (in C), don't check whether there's an overriding
/// definition.
- DefinitionKind isThisDeclarationADefinition() const;
+ DefinitionKind isThisDeclarationADefinition(ASTContext &) const;
+ DefinitionKind isThisDeclarationADefinition() const {
+ return isThisDeclarationADefinition(getASTContext());
+ }
/// \brief Check whether this variable is defined in this
/// translation unit.
- DefinitionKind hasDefinition() const;
+ DefinitionKind hasDefinition(ASTContext &) const;
+ DefinitionKind hasDefinition() const {
+ return hasDefinition(getASTContext());
+ }
/// \brief Get the tentative definition that acts as the real definition in
/// a TU. Returns null if there is a proper definition available.
@@ -965,7 +979,13 @@
bool isTentativeDefinitionNow() const;
/// \brief Get the real (not just tentative) definition for this declaration.
- VarDecl *getDefinition();
+ VarDecl *getDefinition(ASTContext &);
+ const VarDecl *getDefinition(ASTContext &C) const {
+ return const_cast<VarDecl*>(this)->getDefinition(C);
+ }
+ VarDecl *getDefinition() {
+ return getDefinition(getASTContext());
+ }
const VarDecl *getDefinition() const {
return const_cast<VarDecl*>(this)->getDefinition();
}
@@ -1064,7 +1084,7 @@
/// constant expression, according to the relevant language standard.
/// This only checks properties of the declaration, and does not check
/// whether the initializer is in fact a constant expression.
- bool isUsableInConstantExpressions() const;
+ bool isUsableInConstantExpressions(ASTContext &C) const;
EvaluatedStmt *ensureEvaluatedStmt() const;
@@ -1245,7 +1265,7 @@
static ParmVarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- virtual SourceRange getSourceRange() const;
+ virtual SourceRange getSourceRange() const LLVM_READONLY;
void setObjCMethodScopeInfo(unsigned parameterIndex) {
ParmVarDeclBits.IsObjCMethodParam = true;
@@ -1603,7 +1623,7 @@
void setRangeEnd(SourceLocation E) { EndRangeLoc = E; }
- virtual SourceRange getSourceRange() const;
+ virtual SourceRange getSourceRange() const LLVM_READONLY;
/// \brief Returns true if the function has a body (definition). The
/// function body might be in any of the (re-)declarations of this
@@ -2179,7 +2199,7 @@
return cast<RecordDecl>(getDeclContext());
}
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2215,7 +2235,7 @@
void setInitExpr(Expr *E) { Init = (Stmt*) E; }
void setInitVal(const llvm::APSInt &V) { Val = V; }
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2296,9 +2316,9 @@
const Type *getTypeForDecl() const { return TypeForDecl; }
void setTypeForDecl(const Type *TD) { TypeForDecl = TD; }
- SourceLocation getLocStart() const { return LocStart; }
+ SourceLocation getLocStart() const LLVM_READONLY { return LocStart; }
void setLocStart(SourceLocation L) { LocStart = L; }
- virtual SourceRange getSourceRange() const {
+ virtual SourceRange getSourceRange() const LLVM_READONLY {
if (LocStart.isValid())
return SourceRange(LocStart, getLocation());
else
@@ -2382,7 +2402,7 @@
IdentifierInfo *Id, TypeSourceInfo *TInfo);
static TypedefDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2403,7 +2423,7 @@
IdentifierInfo *Id, TypeSourceInfo *TInfo);
static TypeAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2438,7 +2458,7 @@
/// in the syntax of a declarator.
bool IsEmbeddedInDeclarator : 1;
- /// /brief True if this tag is free standing, e.g. "struct foo;".
+ /// \brief True if this tag is free standing, e.g. "struct foo;".
bool IsFreeStanding : 1;
protected:
@@ -2447,7 +2467,7 @@
unsigned NumNegativeBits : 8;
/// IsScoped - True if this tag declaration is a scoped enumeration. Only
- /// possible in C++0x mode.
+ /// possible in C++11 mode.
bool IsScoped : 1;
/// IsScopedUsingClassTag - If this tag declaration is a scoped enum,
/// then this is true if the scoped enum was declared using the class
@@ -2456,7 +2476,7 @@
bool IsScopedUsingClassTag : 1;
/// IsFixed - True if this is an enumeration with fixed underlying type. Only
- /// possible in C++0x mode.
+ /// possible in C++11 or Microsoft extensions mode.
bool IsFixed : 1;
private:
@@ -2526,7 +2546,7 @@
/// getOuterLocStart - Return SourceLocation representing start of source
/// range taking into account any outer template declarations.
SourceLocation getOuterLocStart() const;
- virtual SourceRange getSourceRange() const;
+ virtual SourceRange getSourceRange() const LLVM_READONLY;
virtual TagDecl* getCanonicalDecl();
const TagDecl* getCanonicalDecl() const {
@@ -2651,8 +2671,9 @@
friend class ASTDeclWriter;
};
-/// EnumDecl - Represents an enum. As an extension, we allow forward-declared
-/// enums.
+/// EnumDecl - Represents an enum. In C++11, enums can be forward-declared
+/// with a fixed underlying type, and in C we allow them to be forward-declared
+/// with no underlying type as an extension.
class EnumDecl : public TagDecl {
virtual void anchor();
/// IntegerType - This represent the integer type that the enum corresponds
@@ -2678,10 +2699,10 @@
/// in C++) are of the enum type instead.
QualType PromotionType;
- /// \brief If the enumeration was instantiated from an enumeration
- /// within a class or function template, this pointer refers to the
- /// enumeration declared within the template.
- EnumDecl *InstantiatedFrom;
+ /// \brief If this enumeration is an instantiation of a member enumeration
+ /// of a class template specialization, this is the member specialization
+ /// information.
+ MemberSpecializationInfo *SpecializationInfo;
// The number of positive and negative bits required by the
// enumerators are stored in the SubclassBits field.
@@ -2694,7 +2715,7 @@
IdentifierInfo *Id, EnumDecl *PrevDecl,
bool Scoped, bool ScopedUsingClassTag, bool Fixed)
: TagDecl(Enum, TTK_Enum, DC, IdLoc, Id, PrevDecl, StartLoc),
- InstantiatedFrom(0) {
+ SpecializationInfo(0) {
assert(Scoped || !ScopedUsingClassTag);
IntegerType = (const Type*)0;
NumNegativeBits = 0;
@@ -2703,6 +2724,9 @@
IsScopedUsingClassTag = ScopedUsingClassTag;
IsFixed = Fixed;
}
+
+ void setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED,
+ TemplateSpecializationKind TSK);
public:
EnumDecl *getCanonicalDecl() {
return cast<EnumDecl>(TagDecl::getCanonicalDecl());
@@ -2725,6 +2749,10 @@
return cast<EnumDecl>(TagDecl::getMostRecentDecl());
}
+ EnumDecl *getDefinition() const {
+ return cast_or_null<EnumDecl>(TagDecl::getDefinition());
+ }
+
static EnumDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, EnumDecl *PrevDecl,
@@ -2747,14 +2775,14 @@
typedef specific_decl_iterator<EnumConstantDecl> enumerator_iterator;
enumerator_iterator enumerator_begin() const {
- const EnumDecl *E = cast_or_null<EnumDecl>(getDefinition());
+ const EnumDecl *E = getDefinition();
if (!E)
E = this;
return enumerator_iterator(E->decls_begin());
}
enumerator_iterator enumerator_end() const {
- const EnumDecl *E = cast_or_null<EnumDecl>(getDefinition());
+ const EnumDecl *E = getDefinition();
if (!E)
E = this;
return enumerator_iterator(E->decls_end());
@@ -2839,11 +2867,21 @@
/// \brief Returns the enumeration (declared within the template)
/// from which this enumeration type was instantiated, or NULL if
/// this enumeration was not instantiated from any template.
- EnumDecl *getInstantiatedFromMemberEnum() const {
- return InstantiatedFrom;
+ EnumDecl *getInstantiatedFromMemberEnum() const;
+
+ /// \brief If this enumeration is an instantiation of a member enumeration of
+ /// a class template specialization, retrieves the member specialization
+ /// information.
+ MemberSpecializationInfo *getMemberSpecializationInfo() const {
+ return SpecializationInfo;
}
- void setInstantiationOfMemberEnum(EnumDecl *IF) { InstantiatedFrom = IF; }
+ /// \brief Specify that this enumeration is an instantiation of the
+ /// member enumeration ED.
+ void setInstantiationOfMemberEnum(EnumDecl *ED,
+ TemplateSpecializationKind TSK) {
+ setInstantiationOfMemberEnum(getASTContext(), ED, TSK);
+ }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const EnumDecl *D) { return true; }
@@ -3004,7 +3042,7 @@
SourceLocation getAsmLoc() const { return getLocation(); }
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getAsmLoc(), getRParenLoc());
}
@@ -3155,7 +3193,7 @@
const Capture *end,
bool capturesCXXThis);
- virtual SourceRange getSourceRange() const;
+ virtual SourceRange getSourceRange() const LLVM_READONLY;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -3230,7 +3268,7 @@
/// identifiers aren't available.
ArrayRef<SourceLocation> getIdentifierLocs() const;
- virtual SourceRange getSourceRange() const;
+ virtual SourceRange getSourceRange() const LLVM_READONLY;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const ImportDecl *D) { return true; }
Modified: cfe/branches/tooling/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/DeclBase.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/DeclBase.h (original)
+++ cfe/branches/tooling/include/clang/AST/DeclBase.h Mon Mar 19 14:02:20 2012
@@ -17,8 +17,9 @@
#include "clang/AST/Attr.h"
#include "clang/AST/Type.h"
#include "clang/Basic/Specifiers.h"
-#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/PrettyStackTrace.h"
namespace clang {
class DeclContext;
@@ -337,11 +338,15 @@
public:
/// \brief Source range that this declaration covers.
- virtual SourceRange getSourceRange() const {
+ virtual SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getLocation(), getLocation());
}
- SourceLocation getLocStart() const { return getSourceRange().getBegin(); }
- SourceLocation getLocEnd() const { return getSourceRange().getEnd(); }
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return getSourceRange().getBegin();
+ }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return getSourceRange().getEnd();
+ }
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
@@ -375,7 +380,7 @@
bool isInAnonymousNamespace() const;
- ASTContext &getASTContext() const;
+ ASTContext &getASTContext() const LLVM_READONLY;
void setAccess(AccessSpecifier AS) {
Access = AS;
@@ -944,8 +949,11 @@
/// \brief Pointer to the data structure used to lookup declarations
/// within this context (or a DependentStoredDeclsMap if this is a
- /// dependent context).
- mutable StoredDeclsMap *LookupPtr;
+ /// dependent context), and a bool indicating whether we have lazily
+ /// omitted any declarations from the map. We maintain the invariant
+ /// that, if the map contains an entry for a DeclarationName, then it
+ /// contains all relevant entries for that name.
+ mutable llvm::PointerIntPair<StoredDeclsMap*, 1, bool> LookupPtr;
protected:
/// FirstDecl - The first declaration stored within this declaration
@@ -968,7 +976,7 @@
DeclContext(Decl::Kind K)
: DeclKind(K), ExternalLexicalStorage(false),
- ExternalVisibleStorage(false), LookupPtr(0), FirstDecl(0),
+ ExternalVisibleStorage(false), LookupPtr(0, false), FirstDecl(0),
LastDecl(0) { }
public:
@@ -1427,11 +1435,7 @@
/// visible from this context, as determined by
/// NamedDecl::declarationReplaces, the previous declaration will be
/// replaced with D.
- ///
- /// @param Recoverable true if it's okay to not add this decl to
- /// the lookup tables because it can be easily recovered by walking
- /// the declaration chains.
- void makeDeclVisibleInContext(NamedDecl *D, bool Recoverable = true);
+ void makeDeclVisibleInContext(NamedDecl *D);
/// udir_iterator - Iterates through the using-directives stored
/// within this context.
@@ -1457,7 +1461,11 @@
// Low-level accessors
/// \brief Retrieve the internal representation of the lookup structure.
- StoredDeclsMap* getLookupPtr() const { return LookupPtr; }
+ /// This may omit some names if we are lazily building the structure.
+ StoredDeclsMap *getLookupPtr() const { return LookupPtr.getPointer(); }
+
+ /// \brief Ensure the lookup structure is fully-built and return it.
+ StoredDeclsMap *buildLookup();
/// \brief Whether this DeclContext has external storage containing
/// additional declarations that are lexically in this context.
@@ -1504,15 +1512,14 @@
///
/// Analogous to makeDeclVisibleInContext, but for the exclusive
/// use of addDeclInternal().
- void makeDeclVisibleInContextInternal(NamedDecl *D,
- bool Recoverable = true);
+ void makeDeclVisibleInContextInternal(NamedDecl *D);
friend class DependentDiagnostic;
StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const;
- void buildLookup(DeclContext *DCtx);
+ void buildLookupImpl(DeclContext *DCtx);
void makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal,
- bool Recoverable);
+ bool Rediscoverable);
void makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal);
};
Modified: cfe/branches/tooling/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/DeclCXX.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/DeclCXX.h (original)
+++ cfe/branches/tooling/include/clang/AST/DeclCXX.h Mon Mar 19 14:02:20 2012
@@ -23,6 +23,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/Compiler.h"
namespace clang {
@@ -130,7 +131,7 @@
/// setColonLoc - Sets the location of the colon.
void setColonLoc(SourceLocation CLoc) { ColonLoc = CLoc; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getAccessSpecifierLoc(), getColonLoc());
}
@@ -208,7 +209,9 @@
/// getSourceRange - Retrieves the source range that contains the
/// entire base specifier.
- SourceRange getSourceRange() const { return Range; }
+ SourceRange getSourceRange() const LLVM_READONLY { return Range; }
+ SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
/// isVirtual - Determines whether the base class is a virtual base
/// class (or not).
@@ -1849,7 +1852,7 @@
SourceLocation getSourceLocation() const;
/// \brief Determine the source range covering the entire initializer.
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
/// isWritten - Returns true if this initializer is explicitly written
/// in the source code.
@@ -2332,7 +2335,7 @@
void setExternLoc(SourceLocation L) { ExternLoc = L; }
void setRBraceLoc(SourceLocation L) { RBraceLoc = L; }
- SourceLocation getLocEnd() const {
+ SourceLocation getLocEnd() const LLVM_READONLY {
if (hasBraces())
return getRBraceLoc();
// No braces: get the end location of the (only) declaration in context
@@ -2340,7 +2343,7 @@
return decls_empty() ? getLocation() : decls_begin()->getLocEnd();
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(ExternLoc, getLocEnd());
}
@@ -2444,7 +2447,7 @@
DeclContext *CommonAncestor);
static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(UsingLoc, getLocation());
}
@@ -2536,7 +2539,7 @@
static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- virtual SourceRange getSourceRange() const {
+ virtual SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(NamespaceLoc, IdentLoc);
}
@@ -2731,7 +2734,7 @@
static UsingDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(UsingLocation, getNameInfo().getEndLoc());
}
@@ -2802,7 +2805,7 @@
static UnresolvedUsingValueDecl *
CreateDeserialized(ASTContext &C, unsigned ID);
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(UsingLocation, getNameInfo().getEndLoc());
}
@@ -2904,7 +2907,7 @@
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getLocation(), getRParenLoc());
}
Modified: cfe/branches/tooling/include/clang/AST/DeclFriend.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/DeclFriend.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/DeclFriend.h (original)
+++ cfe/branches/tooling/include/clang/AST/DeclFriend.h Mon Mar 19 14:02:20 2012
@@ -16,6 +16,7 @@
#define LLVM_CLANG_AST_DECLFRIEND_H
#include "clang/AST/DeclCXX.h"
+#include "llvm/Support/Compiler.h"
namespace clang {
@@ -100,7 +101,7 @@
}
/// Retrieves the source range for the friend declaration.
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
/* FIXME: consider the case of templates wrt start of range. */
if (NamedDecl *ND = getFriendDecl())
return SourceRange(getFriendLoc(), ND->getLocEnd());
Modified: cfe/branches/tooling/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/DeclObjC.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/DeclObjC.h (original)
+++ cfe/branches/tooling/include/clang/AST/DeclObjC.h Mon Mar 19 14:02:20 2012
@@ -17,6 +17,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/SelectorLocationsKind.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Compiler.h"
namespace clang {
class Expr;
@@ -281,10 +282,10 @@
void setAsRedeclaration(const ObjCMethodDecl *PrevMethod);
// Location information, modeled after the Stmt API.
- SourceLocation getLocStart() const { return getLocation(); }
- SourceLocation getLocEnd() const { return EndLoc; }
+ SourceLocation getLocStart() const LLVM_READONLY { return getLocation(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; }
void setEndLoc(SourceLocation Loc) { EndLoc = Loc; }
- virtual SourceRange getSourceRange() const {
+ virtual SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getLocation(), EndLoc);
}
@@ -507,7 +508,7 @@
AtEnd = atEnd;
}
- virtual SourceRange getSourceRange() const {
+ virtual SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(AtStart, getAtEndRange().getEnd());
}
@@ -637,7 +638,7 @@
static ObjCInterfaceDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- virtual SourceRange getSourceRange() const {
+ virtual SourceRange getSourceRange() const LLVM_READONLY {
if (isThisDeclarationADefinition())
return ObjCContainerDecl::getSourceRange();
@@ -650,6 +651,7 @@
void setExternallyCompleted();
const ObjCProtocolList &getReferencedProtocols() const {
+ assert(hasDefinition() && "Caller did not check for forward reference!");
if (data().ExternallyCompleted)
LoadExternalDefinition();
@@ -1217,7 +1219,7 @@
/// \brief Starts the definition of this Objective-C protocol.
void startDefinition();
- virtual SourceRange getSourceRange() const {
+ virtual SourceRange getSourceRange() const LLVM_READONLY {
if (isThisDeclarationADefinition())
return ObjCContainerDecl::getSourceRange();
@@ -1868,7 +1870,7 @@
return PropertyIvarDecl;
}
- virtual SourceRange getSourceRange() const {
+ virtual SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(AtLoc, getLocation());
}
@@ -1936,9 +1938,9 @@
static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- virtual SourceRange getSourceRange() const;
+ virtual SourceRange getSourceRange() const LLVM_READONLY;
- SourceLocation getLocStart() const { return AtLoc; }
+ SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
ObjCPropertyDecl *getPropertyDecl() const {
Modified: cfe/branches/tooling/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/DeclTemplate.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/DeclTemplate.h (original)
+++ cfe/branches/tooling/include/clang/AST/DeclTemplate.h Mon Mar 19 14:02:20 2012
@@ -18,6 +18,7 @@
#include "clang/AST/Redeclarable.h"
#include "clang/AST/TemplateBase.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/Support/Compiler.h"
#include <limits>
namespace clang {
@@ -105,7 +106,7 @@
SourceLocation getLAngleLoc() const { return LAngleLoc; }
SourceLocation getRAngleLoc() const { return RAngleLoc; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(TemplateLoc, RAngleLoc);
}
};
@@ -239,7 +240,7 @@
return K >= firstTemplate && K <= lastTemplate;
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(TemplateParams->getTemplateLoc(),
TemplatedDecl->getSourceRange().getEnd());
}
@@ -354,8 +355,8 @@
};
/// \brief Provides information a specialization of a member of a class
-/// template, which may be a member function, static data member, or
-/// member class.
+/// template, which may be a member function, static data member,
+/// member class or member enumeration.
class MemberSpecializationInfo {
// The member declaration from which this member was instantiated, and the
// manner in which the instantiation occurred (in the lower two bits).
@@ -617,8 +618,42 @@
getCommonPtr()->InstantiatedFromMember.setInt(true);
}
- /// \brief Retrieve the previous declaration of this template, or
- /// NULL if no such declaration exists.
+ /// \brief Retrieve the member template from which this template was
+ /// instantiated, or NULL if this template was not instantiated from a
+ /// member template.
+ ///
+ /// A template is instantiated from a member template when the member
+ /// template itself is part of a class template (or member thereof). For
+ /// example, given
+ ///
+ /// \code
+ /// template<typename T>
+ /// struct X {
+ /// template<typename U> void f(T, U);
+ /// };
+ ///
+ /// void test(X<int> x) {
+ /// x.f(1, 'a');
+ /// };
+ /// \endcode
+ ///
+ /// \c X<int>::f is a FunctionTemplateDecl that describes the function
+ /// template
+ ///
+ /// \code
+ /// template<typename U> void X<int>::f(int, U);
+ /// \endcode
+ ///
+ /// which was itself created during the instantiation of \c X<int>. Calling
+ /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will
+ /// retrieve the FunctionTemplateDecl for the original template "f" within
+ /// the class template \c X<T>, i.e.,
+ ///
+ /// \code
+ /// template<typename T>
+ /// template<typename U>
+ /// void X<T>::f(T, U);
+ /// \endcode
RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() {
return getCommonPtr()->InstantiatedFromMember.getPointer();
}
@@ -917,7 +952,7 @@
/// \brief Returns whether this is a parameter pack.
bool isParameterPack() const;
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -995,7 +1030,7 @@
using TemplateParmPosition::setPosition;
using TemplateParmPosition::getIndex;
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
/// \brief Determine whether this template parameter has a default
/// argument.
@@ -1181,7 +1216,7 @@
DefaultArgumentWasInherited = false;
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
SourceLocation End = getLocation();
if (hasDefaultArgument() && !defaultArgumentWasInherited())
End = getDefaultArgument().getSourceRange().getEnd();
@@ -1437,7 +1472,7 @@
return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
}
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
void Profile(llvm::FoldingSetNodeID &ID) const {
Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext());
Modified: cfe/branches/tooling/include/clang/AST/DeclarationName.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/DeclarationName.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/DeclarationName.h (original)
+++ cfe/branches/tooling/include/clang/AST/DeclarationName.h Mon Mar 19 14:02:20 2012
@@ -17,6 +17,7 @@
#include "clang/AST/Type.h"
#include "clang/AST/CanonicalType.h"
#include "clang/Basic/PartialDiagnostic.h"
+#include "llvm/Support/Compiler.h"
namespace llvm {
template <typename T> struct DenseMapInfo;
@@ -510,11 +511,18 @@
/// getEndLoc - Retrieve the location of the last token.
SourceLocation getEndLoc() const;
/// getSourceRange - The range of the declaration name.
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
SourceLocation BeginLoc = getBeginLoc();
SourceLocation EndLoc = getEndLoc();
return SourceRange(BeginLoc, EndLoc.isValid() ? EndLoc : BeginLoc);
}
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return getBeginLoc();
+ }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ SourceLocation EndLoc = getEndLoc();
+ return EndLoc.isValid() ? EndLoc : getLocStart();
+ }
};
/// Insertion operator for diagnostics. This allows sending DeclarationName's
Modified: cfe/branches/tooling/include/clang/AST/DependentDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/DependentDiagnostic.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/DependentDiagnostic.h (original)
+++ cfe/branches/tooling/include/clang/AST/DependentDiagnostic.h Mon Mar 19 14:02:20 2012
@@ -177,7 +177,7 @@
assert(isDependentContext()
&& "cannot iterate dependent diagnostics of non-dependent context");
const DependentStoredDeclsMap *Map
- = static_cast<DependentStoredDeclsMap*>(getPrimaryContext()->LookupPtr);
+ = static_cast<DependentStoredDeclsMap*>(getPrimaryContext()->getLookupPtr());
if (!Map) return ddiag_iterator();
return ddiag_iterator(Map->FirstDiagnostic);
Modified: cfe/branches/tooling/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/Expr.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/Expr.h (original)
+++ cfe/branches/tooling/include/clang/AST/Expr.h Mon Mar 19 14:02:20 2012
@@ -27,6 +27,7 @@
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
#include <cctype>
namespace clang {
@@ -175,7 +176,7 @@
/// getExprLoc - Return the preferred location for the arrow when diagnosing
/// a problem with a generic expression.
- SourceLocation getExprLoc() const;
+ SourceLocation getExprLoc() const LLVM_READONLY;
/// isUnusedResultAWarning - Return true if this immediate expression should
/// be warned about if the result is unused. If so, fill in Loc and Ranges
@@ -235,7 +236,6 @@
MLV_IncompleteType,
MLV_ConstQualified,
MLV_ArrayType,
- MLV_NotBlockQualified,
MLV_ReadonlyProperty,
MLV_NoSetterProperty,
MLV_MemberFunction,
@@ -271,7 +271,6 @@
CM_RValue, // Not modifiable because it's an rvalue
CM_Function, // Not modifiable because it's a function; C++ only
CM_LValueCast, // Same as CM_RValue, but indicates GCC cast-as-lvalue ext
- CM_NotBlockQualified, // Not captured in the closure
CM_NoSetterProperty,// Implicit assignment to ObjC property without setter
CM_ConstQualified,
CM_ArrayType,
@@ -594,50 +593,52 @@
/// IgnoreImpCasts - Skip past any implicit casts which might
/// surround this expression. Only skips ImplicitCastExprs.
- Expr *IgnoreImpCasts();
+ Expr *IgnoreImpCasts() LLVM_READONLY;
/// IgnoreImplicit - Skip past any implicit AST nodes which might
/// surround this expression.
- Expr *IgnoreImplicit() { return cast<Expr>(Stmt::IgnoreImplicit()); }
+ Expr *IgnoreImplicit() LLVM_READONLY {
+ return cast<Expr>(Stmt::IgnoreImplicit());
+ }
/// 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();
+ Expr *IgnoreParens() LLVM_READONLY;
/// IgnoreParenCasts - Ignore parentheses and casts. Strip off any ParenExpr
/// or CastExprs, returning their operand.
- Expr *IgnoreParenCasts();
+ Expr *IgnoreParenCasts() LLVM_READONLY;
/// IgnoreParenImpCasts - Ignore parentheses and implicit casts. Strip off
/// any ParenExpr or ImplicitCastExprs, returning their operand.
- Expr *IgnoreParenImpCasts();
+ Expr *IgnoreParenImpCasts() LLVM_READONLY;
/// IgnoreConversionOperator - Ignore conversion operator. If this Expr is a
/// call to a conversion operator, return the argument.
- Expr *IgnoreConversionOperator();
+ Expr *IgnoreConversionOperator() LLVM_READONLY;
- const Expr *IgnoreConversionOperator() const {
+ const Expr *IgnoreConversionOperator() const LLVM_READONLY {
return const_cast<Expr*>(this)->IgnoreConversionOperator();
}
- const Expr *IgnoreParenImpCasts() const {
+ const Expr *IgnoreParenImpCasts() const LLVM_READONLY {
return const_cast<Expr*>(this)->IgnoreParenImpCasts();
}
/// Ignore parentheses and lvalue casts. Strip off any ParenExpr and
/// CastExprs that represent lvalue casts, returning their operand.
- Expr *IgnoreParenLValueCasts();
+ Expr *IgnoreParenLValueCasts() LLVM_READONLY;
- const Expr *IgnoreParenLValueCasts() const {
+ const Expr *IgnoreParenLValueCasts() const LLVM_READONLY {
return const_cast<Expr*>(this)->IgnoreParenLValueCasts();
}
/// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the
/// value (including ptr->int casts of the same size). Strip off any
/// ParenExpr or CastExprs, returning their operand.
- Expr *IgnoreParenNoopCasts(ASTContext &Ctx);
+ Expr *IgnoreParenNoopCasts(ASTContext &Ctx) LLVM_READONLY;
/// \brief Determine whether this expression is a default function argument.
///
@@ -655,16 +656,16 @@
/// \brief Whether this expression is an implicit reference to 'this' in C++.
bool isImplicitCXXThis() const;
- const Expr *IgnoreImpCasts() const {
+ const Expr *IgnoreImpCasts() const LLVM_READONLY {
return const_cast<Expr*>(this)->IgnoreImpCasts();
}
- const Expr *IgnoreParens() const {
+ const Expr *IgnoreParens() const LLVM_READONLY {
return const_cast<Expr*>(this)->IgnoreParens();
}
- const Expr *IgnoreParenCasts() const {
+ const Expr *IgnoreParenCasts() const LLVM_READONLY {
return const_cast<Expr*>(this)->IgnoreParenCasts();
}
- const Expr *IgnoreParenNoopCasts(ASTContext &Ctx) const {
+ const Expr *IgnoreParenNoopCasts(ASTContext &Ctx) const LLVM_READONLY {
return const_cast<Expr*>(this)->IgnoreParenNoopCasts(Ctx);
}
@@ -716,11 +717,11 @@
/// \brief Retrieve the location of this expression.
SourceLocation getLocation() const { return Loc; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
if (SourceExpr) return SourceExpr->getSourceRange();
return Loc;
}
- SourceLocation getExprLoc() const {
+ SourceLocation getExprLoc() const LLVM_READONLY {
if (SourceExpr) return SourceExpr->getExprLoc();
return Loc;
}
@@ -763,6 +764,9 @@
/// DeclRefExprBits.HasTemplateKWAndArgsInfo:
/// Specifies when this declaration reference expression has an explicit
/// C++ template keyword and/or template argument list.
+/// DeclRefExprBits.RefersToEnclosingLocal
+/// Specifies when this declaration reference expression (validly)
+/// refers to a local variable from a different function.
class DeclRefExpr : public Expr {
/// \brief The declaration that we are referencing.
ValueDecl *D;
@@ -804,9 +808,11 @@
return const_cast<DeclRefExpr *>(this)->getInternalFoundDecl();
}
- DeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
+ DeclRefExpr(ASTContext &Ctx,
+ NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
- ValueDecl *D, const DeclarationNameInfo &NameInfo,
+ ValueDecl *D, bool refersToEnclosingLocal,
+ const DeclarationNameInfo &NameInfo,
NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs,
QualType T, ExprValueKind VK);
@@ -817,10 +823,11 @@
/// \brief Computes the type- and value-dependence flags for this
/// declaration reference expression.
- void computeDependence();
+ void computeDependence(ASTContext &C);
public:
- DeclRefExpr(ValueDecl *D, QualType T, ExprValueKind VK, SourceLocation L,
+ DeclRefExpr(ValueDecl *D, bool refersToEnclosingLocal, QualType T,
+ ExprValueKind VK, SourceLocation L,
const DeclarationNameLoc &LocInfo = DeclarationNameLoc())
: Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false),
D(D), Loc(L), DNLoc(LocInfo) {
@@ -828,13 +835,15 @@
DeclRefExprBits.HasTemplateKWAndArgsInfo = 0;
DeclRefExprBits.HasFoundDecl = 0;
DeclRefExprBits.HadMultipleCandidates = 0;
- computeDependence();
+ DeclRefExprBits.RefersToEnclosingLocal = refersToEnclosingLocal;
+ computeDependence(D->getASTContext());
}
static DeclRefExpr *Create(ASTContext &Context,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
ValueDecl *D,
+ bool isEnclosingLocal,
SourceLocation NameLoc,
QualType T, ExprValueKind VK,
NamedDecl *FoundD = 0,
@@ -844,6 +853,7 @@
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
ValueDecl *D,
+ bool isEnclosingLocal,
const DeclarationNameInfo &NameInfo,
QualType T, ExprValueKind VK,
NamedDecl *FoundD = 0,
@@ -866,7 +876,9 @@
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
+ SourceLocation getLocStart() const LLVM_READONLY;
+ SourceLocation getLocEnd() const LLVM_READONLY;
/// \brief Determine whether this declaration reference was preceded by a
/// C++ nested-name-specifier, e.g., \c N::foo.
@@ -1017,6 +1029,12 @@
DeclRefExprBits.HadMultipleCandidates = V;
}
+ /// Does this DeclRefExpr refer to a local declaration from an
+ /// enclosing function scope?
+ bool refersToEnclosingLocal() const {
+ return DeclRefExprBits.RefersToEnclosingLocal;
+ }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == DeclRefExprClass;
}
@@ -1064,7 +1082,7 @@
static std::string ComputeName(IdentType IT, const Decl *CurrentDecl);
- SourceRange getSourceRange() const { return SourceRange(Loc); }
+ SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == PredefinedExprClass;
@@ -1154,7 +1172,7 @@
/// \brief Returns a new empty integer literal.
static IntegerLiteral *Create(ASTContext &C, EmptyShell Empty);
- SourceRange getSourceRange() const { return SourceRange(Loc); }
+ SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); }
/// \brief Retrieve the location of the literal.
SourceLocation getLocation() const { return Loc; }
@@ -1200,7 +1218,7 @@
return static_cast<CharacterKind>(CharacterLiteralBits.Kind);
}
- SourceRange getSourceRange() const { return SourceRange(Loc); }
+ SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); }
unsigned getValue() const { return Value; }
@@ -1261,7 +1279,7 @@
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
- SourceRange getSourceRange() const { return SourceRange(Loc); }
+ SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == FloatingLiteralClass;
@@ -1293,7 +1311,7 @@
Expr *getSubExpr() { return cast<Expr>(Val); }
void setSubExpr(Expr *E) { Val = E; }
- SourceRange getSourceRange() const { return Val->getSourceRange(); }
+ SourceRange getSourceRange() const LLVM_READONLY { return Val->getSourceRange(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ImaginaryLiteralClass;
}
@@ -1451,7 +1469,7 @@
tokloc_iterator tokloc_begin() const { return TokLocs; }
tokloc_iterator tokloc_end() const { return TokLocs+NumConcatenated; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(TokLocs[0], TokLocs[NumConcatenated-1]);
}
static bool classof(const Stmt *T) {
@@ -1485,7 +1503,7 @@
Expr *getSubExpr() { return cast<Expr>(Val); }
void setSubExpr(Expr *E) { Val = E; }
- SourceRange getSourceRange() const { return SourceRange(L, R); }
+ SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(L, R); }
/// \brief Get the location of the left parentheses '('.
SourceLocation getLParen() const { return L; }
@@ -1598,13 +1616,13 @@
/// the given unary opcode.
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc);
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
if (isPostfix())
return SourceRange(Val->getLocStart(), Loc);
else
return SourceRange(Loc, Val->getLocEnd());
}
- SourceLocation getExprLoc() const { return Loc; }
+ SourceLocation getExprLoc() const LLVM_READONLY { return Loc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == UnaryOperatorClass;
@@ -1720,7 +1738,7 @@
/// the square brackets. For a field or identifier node, the source range
/// contains the location of the period (if there is one) and the
/// identifier.
- SourceRange getSourceRange() const { return Range; }
+ SourceRange getSourceRange() const LLVM_READONLY { return Range; }
};
private:
@@ -1802,7 +1820,7 @@
return NumExprs;
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(OperatorLoc, RParenLoc);
}
@@ -1908,7 +1926,7 @@
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(OpLoc, RParenLoc);
}
@@ -1983,14 +2001,14 @@
return cast<Expr>(getRHS()->getType()->isIntegerType() ? getRHS():getLHS());
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getLHS()->getLocStart(), RBracketLoc);
}
SourceLocation getRBracketLoc() const { return RBracketLoc; }
void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }
- SourceLocation getExprLoc() const { return getBase()->getExprLoc(); }
+ SourceLocation getExprLoc() const LLVM_READONLY { return getBase()->getExprLoc(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ArraySubscriptExprClass;
@@ -2123,7 +2141,9 @@
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
+ SourceLocation getLocStart() const LLVM_READONLY;
+ SourceLocation getLocEnd() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() >= firstCallExprConstant &&
@@ -2390,9 +2410,11 @@
SourceLocation getMemberLoc() const { return MemberLoc; }
void setMemberLoc(SourceLocation L) { MemberLoc = L; }
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
+ SourceLocation getLocStart() const LLVM_READONLY;
+ SourceLocation getLocEnd() const LLVM_READONLY;
- SourceLocation getExprLoc() const { return MemberLoc; }
+ SourceLocation getExprLoc() const LLVM_READONLY { return MemberLoc; }
/// \brief Determine whether the base of this explicit is implicit.
bool isImplicitAccess() const {
@@ -2468,7 +2490,7 @@
TInfoAndScope.setPointer(tinfo);
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
// FIXME: Init should never be null.
if (!Init)
return SourceRange();
@@ -2622,9 +2644,15 @@
static ImplicitCastExpr *CreateEmpty(ASTContext &Context, unsigned PathSize);
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return getSubExpr()->getSourceRange();
}
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return getSubExpr()->getLocStart();
+ }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return getSubExpr()->getLocEnd();
+ }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ImplicitCastExprClass;
@@ -2719,7 +2747,7 @@
SourceLocation getRParenLoc() const { return RPLoc; }
void setRParenLoc(SourceLocation L) { RPLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(LPLoc, getSubExpr()->getSourceRange().getEnd());
}
static bool classof(const Stmt *T) {
@@ -2779,7 +2807,7 @@
explicit BinaryOperator(EmptyShell Empty)
: Expr(BinaryOperatorClass, Empty), Opc(BO_Comma) { }
- SourceLocation getExprLoc() const { return OpLoc; }
+ SourceLocation getExprLoc() const LLVM_READONLY { return OpLoc; }
SourceLocation getOperatorLoc() const { return OpLoc; }
void setOperatorLoc(SourceLocation L) { OpLoc = L; }
@@ -2791,7 +2819,7 @@
Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
void setRHS(Expr *E) { SubExprs[RHS] = E; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getLHS()->getLocStart(), getRHS()->getLocEnd());
}
@@ -3022,7 +3050,7 @@
Expr *getLHS() const { return cast<Expr>(SubExprs[LHS]); }
Expr *getRHS() const { return cast<Expr>(SubExprs[RHS]); }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getCond()->getLocStart(), getRHS()->getLocEnd());
}
static bool classof(const Stmt *T) {
@@ -3104,7 +3132,7 @@
return cast<Expr>(SubExprs[RHS]);
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getCommon()->getLocStart(), getFalseExpr()->getLocEnd());
}
static bool classof(const Stmt *T) {
@@ -3156,7 +3184,7 @@
SourceLocation getLabelLoc() const { return LabelLoc; }
void setLabelLoc(SourceLocation L) { LabelLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(AmpAmpLoc, LabelLoc);
}
@@ -3198,7 +3226,7 @@
const CompoundStmt *getSubStmt() const { return cast<CompoundStmt>(SubStmt); }
void setSubStmt(CompoundStmt *S) { SubStmt = S; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(LParenLoc, RParenLoc);
}
@@ -3248,7 +3276,7 @@
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(BuiltinLoc, RParenLoc);
}
static bool classof(const Stmt *T) {
@@ -3343,7 +3371,7 @@
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(BuiltinLoc, RParenLoc);
}
static bool classof(const Stmt *T) {
@@ -3380,7 +3408,7 @@
SourceLocation getTokenLocation() const { return TokenLoc; }
void setTokenLocation(SourceLocation L) { TokenLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(TokenLoc);
}
static bool classof(const Stmt *T) {
@@ -3426,7 +3454,7 @@
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(BuiltinLoc, RParenLoc);
}
static bool classof(const Stmt *T) {
@@ -3606,7 +3634,7 @@
InitListExprBits.InitializesStdInitializerList = ISIL;
}
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == InitListExprClass;
@@ -3842,7 +3870,7 @@
SourceLocation getEndLocation() const {
return Kind == FieldDesignator ? getFieldLoc() : getRBracketLoc();
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getStartLocation(), getEndLocation());
}
};
@@ -3944,7 +3972,7 @@
SourceRange getDesignatorsSourceRange() const;
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == DesignatedInitExprClass;
@@ -3981,7 +4009,7 @@
}
static bool classof(const ImplicitValueInitExpr *) { return true; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange();
}
@@ -4019,7 +4047,7 @@
SourceLocation getLParenLoc() const { return LParenLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(LParenLoc, RParenLoc);
}
static bool classof(const Stmt *T) {
@@ -4134,7 +4162,7 @@
const Expr *getResultExpr() const { return getAssocExpr(getResultIndex()); }
Expr *getResultExpr() { return getAssocExpr(getResultIndex()); }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(GenericLoc, RParenLoc);
}
static bool classof(const Stmt *T) {
@@ -4200,7 +4228,7 @@
/// aggregate Constant of ConstantInt(s).
void getEncodedElementAccess(SmallVectorImpl<unsigned> &Elts) const;
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getBase()->getLocStart(), AccessorLoc);
}
@@ -4243,7 +4271,7 @@
const Stmt *getBody() const;
Stmt *getBody();
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getCaretLocation(), getBody()->getLocEnd());
}
@@ -4259,46 +4287,6 @@
child_range children() { return child_range(); }
};
-/// BlockDeclRefExpr - A reference to a local variable declared in an
-/// enclosing scope.
-class BlockDeclRefExpr : public Expr {
- VarDecl *D;
- SourceLocation Loc;
- bool IsByRef : 1;
- bool ConstQualAdded : 1;
-public:
- BlockDeclRefExpr(VarDecl *d, QualType t, ExprValueKind VK,
- SourceLocation l, bool ByRef, bool constAdded = false);
-
- // \brief Build an empty reference to a declared variable in a
- // block.
- explicit BlockDeclRefExpr(EmptyShell Empty)
- : Expr(BlockDeclRefExprClass, Empty) { }
-
- VarDecl *getDecl() { return D; }
- const VarDecl *getDecl() const { return D; }
- void setDecl(VarDecl *VD) { D = VD; }
-
- SourceLocation getLocation() const { return Loc; }
- void setLocation(SourceLocation L) { Loc = L; }
-
- SourceRange getSourceRange() const { return SourceRange(Loc); }
-
- bool isByRef() const { return IsByRef; }
- void setByRef(bool BR) { IsByRef = BR; }
-
- bool isConstQualAdded() const { return ConstQualAdded; }
- void setConstQualAdded(bool C) { ConstQualAdded = C; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == BlockDeclRefExprClass;
- }
- static bool classof(const BlockDeclRefExpr *) { return true; }
-
- // Iterators
- child_range children() { return child_range(); }
-};
-
/// AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2]
/// This AST node provides support for reinterpreting a type to another
/// type of the same size.
@@ -4333,7 +4321,7 @@
/// getRParenLoc - Return the location of final right parenthesis.
SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(BuiltinLoc, RParenLoc);
}
@@ -4462,10 +4450,10 @@
return const_cast<PseudoObjectExpr*>(this)->getSemanticExpr(index);
}
- SourceLocation getExprLoc() const {
+ SourceLocation getExprLoc() const LLVM_READONLY {
return getSyntacticForm()->getExprLoc();
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return getSyntacticForm()->getSourceRange();
}
@@ -4567,7 +4555,7 @@
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(BuiltinLoc, RParenLoc);
}
static bool classof(const Stmt *T) {
Modified: cfe/branches/tooling/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/ExprCXX.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/ExprCXX.h (original)
+++ cfe/branches/tooling/include/clang/AST/ExprCXX.h Mon Mar 19 14:02:20 2012
@@ -20,6 +20,7 @@
#include "clang/Basic/ExpressionTraits.h"
#include "clang/Basic/Lambda.h"
#include "clang/Basic/TypeTraits.h"
+#include "llvm/Support/Compiler.h"
namespace clang {
@@ -73,7 +74,7 @@
/// bracket.
SourceLocation getOperatorLoc() const { return getRParenLoc(); }
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXOperatorCallExprClass;
@@ -183,7 +184,7 @@
/// \brief Retrieve the location of the closing parenthesis.
SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(Loc, RParenLoc);
}
static bool classof(const Stmt *T) {
@@ -402,7 +403,7 @@
bool getValue() const { return Value; }
void setValue(bool V) { Value = V; }
- SourceRange getSourceRange() const { return SourceRange(Loc); }
+ SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); }
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
@@ -428,7 +429,7 @@
explicit CXXNullPtrLiteralExpr(EmptyShell Empty)
: Expr(CXXNullPtrLiteralExprClass, Empty) { }
- SourceRange getSourceRange() const { return SourceRange(Loc); }
+ SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); }
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
@@ -507,7 +508,7 @@
Operand = E;
}
- SourceRange getSourceRange() const { return Range; }
+ SourceRange getSourceRange() const LLVM_READONLY { return Range; }
void setSourceRange(SourceRange R) { Range = R; }
static bool classof(const Stmt *T) {
@@ -582,7 +583,7 @@
Operand = E;
}
- SourceRange getSourceRange() const { return Range; }
+ SourceRange getSourceRange() const LLVM_READONLY { return Range; }
void setSourceRange(SourceRange R) { Range = R; }
static bool classof(const Stmt *T) {
@@ -628,7 +629,7 @@
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
- SourceRange getSourceRange() const { return SourceRange(Loc); }
+ SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); }
bool isImplicit() const { return Implicit; }
void setImplicit(bool I) { Implicit = I; }
@@ -678,7 +679,7 @@
/// this variable.
bool isThrownVariableInScope() const { return IsThrownVariableInScope; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
if (getSubExpr() == 0)
return SourceRange(ThrowLoc, ThrowLoc);
return SourceRange(ThrowLoc, getSubExpr()->getSourceRange().getEnd());
@@ -766,7 +767,7 @@
/// used.
SourceLocation getUsedLocation() const { return Loc; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
// Default argument expressions have no representation in the
// source, so they have an empty source range.
return SourceRange();
@@ -844,7 +845,7 @@
Expr *getSubExpr() { return cast<Expr>(SubExpr); }
void setSubExpr(Expr *E) { SubExpr = E; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SubExpr->getSourceRange();
}
@@ -980,7 +981,7 @@
Args[Arg] = ArgExpr;
}
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
SourceRange getParenRange() const { return ParenRange; }
static bool classof(const Stmt *T) {
@@ -1032,7 +1033,7 @@
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(TyBeginLoc, RParenLoc);
}
static bool classof(const Stmt *T) {
@@ -1071,7 +1072,7 @@
TypeSourceInfo *getTypeSourceInfo() const { return Type; }
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXTemporaryObjectExprClass;
@@ -1370,7 +1371,7 @@
}
static bool classof(const LambdaExpr *) { return true; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(IntroducerRange.getBegin(), ClosingBrace);
}
@@ -1411,7 +1412,7 @@
SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXScalarValueInitExprClass;
@@ -1552,6 +1553,11 @@
return hasInitializer() ? cast<Expr>(SubExprs[Array]) : 0;
}
+ /// \brief Returns the CXXConstructExpr from this new-expression, or NULL.
+ const CXXConstructExpr* getConstructExpr() {
+ return dyn_cast_or_null<CXXConstructExpr>(getInitializer());
+ }
+
/// Answers whether the usual array deallocation function for the
/// allocated type expects the size of the allocation as a
/// parameter.
@@ -1590,7 +1596,7 @@
SourceRange getDirectInitRange() const { return DirectInitRange; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getStartLoc(), getEndLoc());
}
@@ -1661,7 +1667,7 @@
/// return an invalid type.
QualType getDestroyedType() const;
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(Loc, Argument->getLocEnd());
}
@@ -1853,7 +1859,7 @@
DestroyedType = PseudoDestructorTypeStorage(Info);
}
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXPseudoDestructorExprClass;
@@ -1898,7 +1904,7 @@
: Expr(UnaryTypeTraitExprClass, Empty), UTT(0), Value(false),
QueriedType() { }
- SourceRange getSourceRange() const { return SourceRange(Loc, RParen);}
+ SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc, RParen);}
UnaryTypeTrait getTrait() const { return static_cast<UnaryTypeTrait>(UTT); }
@@ -1961,7 +1967,7 @@
: Expr(BinaryTypeTraitExprClass, Empty), BTT(0), Value(false),
LhsType(), RhsType() { }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(Loc, RParen);
}
@@ -2069,7 +2075,7 @@
return getTypeSourceInfos() + getNumArgs();
}
- SourceRange getSourceRange() const { return SourceRange(Loc, RParenLoc); }
+ SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc, RParenLoc); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == TypeTraitExprClass;
@@ -2129,7 +2135,7 @@
virtual ~ArrayTypeTraitExpr() { }
- virtual SourceRange getSourceRange() const {
+ virtual SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(Loc, RParen);
}
@@ -2188,7 +2194,7 @@
: Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false),
QueriedExpression() { }
- SourceRange getSourceRange() const { return SourceRange(Loc, RParen);}
+ SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc, RParen);}
ExpressionTrait getTrait() const { return static_cast<ExpressionTrait>(ET); }
@@ -2493,7 +2499,7 @@
/// that was looked in to find these results.
CXXRecordDecl *getNamingClass() const { return NamingClass; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
SourceRange Range(getNameInfo().getSourceRange());
if (getQualifierLoc())
Range.setBegin(getQualifierLoc().getBeginLoc());
@@ -2648,7 +2654,7 @@
return getExplicitTemplateArgs().NumTemplateArgs;
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
SourceRange Range(QualifierLoc.getBeginLoc(), getLocation());
if (hasExplicitTemplateArgs())
Range.setEnd(getRAngleLoc());
@@ -2723,7 +2729,7 @@
/// when modifying an existing AST to preserve its invariants.
void setSubExpr(Expr *E) { SubExpr = E; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SubExpr->getSourceRange();
}
@@ -2841,7 +2847,7 @@
*(arg_begin() + I) = E;
}
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXUnresolvedConstructExprClass;
@@ -3076,7 +3082,7 @@
return getExplicitTemplateArgs().NumTemplateArgs;
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
SourceRange Range;
if (!isImplicitAccess())
Range.setBegin(Base->getSourceRange().getBegin());
@@ -3214,7 +3220,7 @@
// expression refers to.
SourceLocation getMemberLoc() const { return getNameLoc(); }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
SourceRange Range = getMemberNameInfo().getSourceRange();
if (!isImplicitAccess())
Range.setBegin(Base->getSourceRange().getBegin());
@@ -3266,7 +3272,7 @@
Expr *getOperand() const { return static_cast<Expr*>(Operand); }
- SourceRange getSourceRange() const { return Range; }
+ SourceRange getSourceRange() const LLVM_READONLY { return Range; }
bool getValue() const { return Value; }
@@ -3343,7 +3349,7 @@
return llvm::Optional<unsigned>();
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(Pattern->getLocStart(), EllipsisLoc);
}
@@ -3449,7 +3455,7 @@
return Length;
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(OperatorLoc, RParenLoc);
}
@@ -3492,7 +3498,7 @@
Param(param), Replacement(replacement), NameLoc(loc) {}
SourceLocation getNameLoc() const { return NameLoc; }
- SourceRange getSourceRange() const { return NameLoc; }
+ SourceRange getSourceRange() const LLVM_READONLY { return NameLoc; }
Expr *getReplacement() const { return cast<Expr>(Replacement); }
@@ -3556,7 +3562,7 @@
/// template arguments.
TemplateArgument getArgumentPack() const;
- SourceRange getSourceRange() const { return NameLoc; }
+ SourceRange getSourceRange() const LLVM_READONLY { return NameLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == SubstNonTypeTemplateParmPackExprClass;
@@ -3616,7 +3622,9 @@
return getValueKind() == VK_LValue;
}
- SourceRange getSourceRange() const { return Temporary->getSourceRange(); }
+ SourceRange getSourceRange() const LLVM_READONLY {
+ return Temporary->getSourceRange();
+ }
static bool classof(const Stmt *T) {
return T->getStmtClass() == MaterializeTemporaryExprClass;
Modified: cfe/branches/tooling/include/clang/AST/ExprObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/ExprObjC.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/ExprObjC.h (original)
+++ cfe/branches/tooling/include/clang/AST/ExprObjC.h Mon Mar 19 14:02:20 2012
@@ -18,6 +18,7 @@
#include "clang/AST/Expr.h"
#include "clang/AST/SelectorLocationsKind.h"
#include "clang/Basic/IdentifierTable.h"
+#include "llvm/Support/Compiler.h"
namespace clang {
class IdentifierInfo;
@@ -43,7 +44,7 @@
SourceLocation getAtLoc() const { return AtLoc; }
void setAtLoc(SourceLocation L) { AtLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(AtLoc, String->getLocEnd());
}
@@ -72,7 +73,7 @@
bool getValue() const { return Value; }
void setValue(bool V) { Value = V; }
- SourceRange getSourceRange() const { return SourceRange(Loc); }
+ SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(Loc); }
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
@@ -111,7 +112,7 @@
SourceLocation getAtLoc() const { return AtLoc; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(AtLoc, Number->getSourceRange().getEnd());
}
@@ -148,7 +149,7 @@
static ObjCArrayLiteral *CreateEmpty(ASTContext &C, unsigned NumElements);
- SourceRange getSourceRange() const { return Range; }
+ SourceRange getSourceRange() const LLVM_READONLY { return Range; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCArrayLiteralClass;
@@ -311,7 +312,7 @@
ObjCMethodDecl *getDictWithObjectsMethod() const
{ return DictWithObjectsMethod; }
- SourceRange getSourceRange() const { return Range; }
+ SourceRange getSourceRange() const LLVM_READONLY { return Range; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCDictionaryLiteralClass;
@@ -362,7 +363,7 @@
EncodedType = EncType;
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(AtLoc, RParenLoc);
}
@@ -396,7 +397,7 @@
void setAtLoc(SourceLocation L) { AtLoc = L; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(AtLoc, RParenLoc);
}
@@ -436,7 +437,7 @@
void setAtLoc(SourceLocation L) { AtLoc = L; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(AtLoc, RParenLoc);
}
@@ -486,7 +487,7 @@
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return isFreeIvar() ? SourceRange(Loc)
: SourceRange(getBase()->getLocStart(), Loc);
}
@@ -666,7 +667,7 @@
bool isSuperReceiver() const { return Receiver.is<const Type*>(); }
bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange((isObjectReceiver() ? getBase()->getLocStart()
: getReceiverLocation()),
IdLoc);
@@ -753,7 +754,7 @@
SourceLocation getRBracket() const { return RBracket; }
void setRBracket(SourceLocation RB) { RBracket = RB; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(SubExprs[BASE]->getLocStart(), RBracket);
}
@@ -1290,7 +1291,7 @@
LBracLoc = R.getBegin();
RBracLoc = R.getEnd();
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(LBracLoc, RBracLoc);
}
@@ -1353,11 +1354,11 @@
SourceLocation getIsaMemberLoc() const { return IsaMemberLoc; }
void setIsaMemberLoc(SourceLocation L) { IsaMemberLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getBase()->getLocStart(), IsaMemberLoc);
}
- SourceLocation getExprLoc() const { return IsaMemberLoc; }
+ SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; }
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCIsaExprClass;
@@ -1426,8 +1427,12 @@
child_range children() { return child_range(&Operand, &Operand+1); }
// Source locations are determined by the subexpression.
- SourceRange getSourceRange() const { return Operand->getSourceRange(); }
- SourceLocation getExprLoc() const { return getSubExpr()->getExprLoc(); }
+ SourceRange getSourceRange() const LLVM_READONLY {
+ return Operand->getSourceRange();
+ }
+ SourceLocation getExprLoc() const LLVM_READONLY {
+ return getSubExpr()->getExprLoc();
+ }
static bool classof(const Stmt *s) {
return s->getStmtClass() == ObjCIndirectCopyRestoreExprClass;
@@ -1474,7 +1479,7 @@
/// \brief The location of the bridge keyword.
SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(LParenLoc, getSubExpr()->getLocEnd());
}
Modified: cfe/branches/tooling/include/clang/AST/NestedNameSpecifier.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/NestedNameSpecifier.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/NestedNameSpecifier.h (original)
+++ cfe/branches/tooling/include/clang/AST/NestedNameSpecifier.h Mon Mar 19 14:02:20 2012
@@ -17,6 +17,7 @@
#include "clang/Basic/Diagnostic.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Compiler.h"
namespace clang {
@@ -248,7 +249,7 @@
/// For example, if this instance refers to a nested-name-specifier
/// \c ::std::vector<int>::, the returned source range would cover
/// from the initial '::' to the last '::'.
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
/// \brief Retrieve the source range covering just the last part of
/// this nested-name-specifier, not including the prefix.
@@ -339,14 +340,18 @@
unsigned BufferCapacity;
public:
- NestedNameSpecifierLocBuilder();
+ NestedNameSpecifierLocBuilder()
+ : Representation(0), Buffer(0), BufferSize(0), BufferCapacity(0) { }
NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
NestedNameSpecifierLocBuilder &
operator=(const NestedNameSpecifierLocBuilder &Other);
- ~NestedNameSpecifierLocBuilder();
+ ~NestedNameSpecifierLocBuilder() {
+ if (BufferCapacity)
+ free(Buffer);
+ }
/// \brief Retrieve the representation of the nested-name-specifier.
NestedNameSpecifier *getRepresentation() const { return Representation; }
@@ -426,7 +431,7 @@
void Adopt(NestedNameSpecifierLoc Other);
/// \brief Retrieve the source range covered by this nested-name-specifier.
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange();
}
Modified: cfe/branches/tooling/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/RecursiveASTVisitor.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/branches/tooling/include/clang/AST/RecursiveASTVisitor.h Mon Mar 19 14:02:20 2012
@@ -148,6 +148,12 @@
/// TypeLocs.
bool shouldWalkTypesOfTypeLocs() const { return true; }
+ /// \brief Return whether \param S should be traversed using data recursion
+ /// to avoid a stack overflow with extreme cases.
+ bool shouldUseDataRecursionFor(Stmt *S) const {
+ return isa<BinaryOperator>(S) || isa<UnaryOperator>(S) || isa<CaseStmt>(S);
+ }
+
/// \brief Recursively visit a statement or expression, by
/// dispatching to Traverse*() based on the argument's dynamic type.
///
@@ -397,8 +403,102 @@
bool TraverseDeclContextHelper(DeclContext *DC);
bool TraverseFunctionHelper(FunctionDecl *D);
bool TraverseVarHelper(VarDecl *D);
+
+ bool Walk(Stmt *S);
+
+ struct EnqueueJob {
+ Stmt *S;
+ Stmt::child_iterator StmtIt;
+
+ EnqueueJob(Stmt *S) : S(S), StmtIt() {
+ if (Expr *E = dyn_cast_or_null<Expr>(S))
+ S = E->IgnoreParens();
+ }
+ };
+ bool dataTraverse(Stmt *S);
};
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::dataTraverse(Stmt *S) {
+
+ SmallVector<EnqueueJob, 16> Queue;
+ Queue.push_back(S);
+
+ while (!Queue.empty()) {
+ EnqueueJob &job = Queue.back();
+ Stmt *CurrS = job.S;
+ if (!CurrS) {
+ Queue.pop_back();
+ continue;
+ }
+
+ if (getDerived().shouldUseDataRecursionFor(CurrS)) {
+ if (job.StmtIt == Stmt::child_iterator()) {
+ if (!Walk(CurrS)) return false;
+ job.StmtIt = CurrS->child_begin();
+ } else {
+ ++job.StmtIt;
+ }
+
+ if (job.StmtIt != CurrS->child_end())
+ Queue.push_back(*job.StmtIt);
+ else
+ Queue.pop_back();
+ continue;
+ }
+
+ Queue.pop_back();
+ TRY_TO(TraverseStmt(CurrS));
+ }
+
+ return true;
+}
+
+template<typename Derived>
+bool RecursiveASTVisitor<Derived>::Walk(Stmt *S) {
+
+#define DISPATCH_WALK(NAME, CLASS, VAR) \
+ return getDerived().WalkUpFrom##NAME(static_cast<CLASS*>(VAR));
+
+ if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
+ switch (BinOp->getOpcode()) {
+#define OPERATOR(NAME) \
+ case BO_##NAME: DISPATCH_WALK(Bin##NAME, BinaryOperator, S);
+
+ BINOP_LIST()
+#undef OPERATOR
+
+#define OPERATOR(NAME) \
+ case BO_##NAME##Assign: \
+ DISPATCH_WALK(Bin##NAME##Assign, CompoundAssignOperator, S);
+
+ CAO_LIST()
+#undef OPERATOR
+ }
+ } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
+ switch (UnOp->getOpcode()) {
+#define OPERATOR(NAME) \
+ case UO_##NAME: DISPATCH_WALK(Unary##NAME, UnaryOperator, S);
+
+ UNARYOP_LIST()
+#undef OPERATOR
+ }
+ }
+
+ // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
+ switch (S->getStmtClass()) {
+ case Stmt::NoStmtClass: break;
+#define ABSTRACT_STMT(STMT)
+#define STMT(CLASS, PARENT) \
+ case Stmt::CLASS##Class: DISPATCH_WALK(CLASS, CLASS, S);
+#include "clang/AST/StmtNodes.inc"
+ }
+
+#undef DISPATCH_WALK
+
+ return true;
+}
+
#define DISPATCH(NAME, CLASS, VAR) \
return getDerived().Traverse##NAME(static_cast<CLASS*>(VAR))
@@ -407,6 +507,9 @@
if (!S)
return true;
+ if (getDerived().shouldUseDataRecursionFor(S))
+ return dataTraverse(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.
@@ -2015,7 +2118,6 @@
// over the children.
DEF_TRAVERSE_STMT(AddrLabelExpr, { })
DEF_TRAVERSE_STMT(ArraySubscriptExpr, { })
-DEF_TRAVERSE_STMT(BlockDeclRefExpr, { })
DEF_TRAVERSE_STMT(BlockExpr, {
TRY_TO(TraverseDecl(S->getBlockDecl()));
return true; // no child statements to loop through.
Modified: cfe/branches/tooling/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/Stmt.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/Stmt.h (original)
+++ cfe/branches/tooling/include/clang/AST/Stmt.h Mon Mar 19 14:02:20 2012
@@ -20,8 +20,9 @@
#include "clang/AST/StmtIterator.h"
#include "clang/AST/DeclGroup.h"
#include "clang/AST/ASTContext.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/raw_ostream.h"
#include <string>
namespace llvm {
@@ -193,6 +194,7 @@
unsigned HasTemplateKWAndArgsInfo : 1;
unsigned HasFoundDecl : 1;
unsigned HadMultipleCandidates : 1;
+ unsigned RefersToEnclosingLocal : 1;
};
class CastExprBitfields {
@@ -346,10 +348,9 @@
/// 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.
- SourceRange getSourceRange() const;
-
- SourceLocation getLocStart() const { return getSourceRange().getBegin(); }
- SourceLocation getLocEnd() const { return getSourceRange().getEnd(); }
+ SourceRange getSourceRange() const LLVM_READONLY;
+ SourceLocation getLocStart() const LLVM_READONLY;
+ SourceLocation getLocEnd() const LLVM_READONLY;
// global temp stats (until we have a per-module visitor)
static void addStmtClass(const StmtClass s);
@@ -475,7 +476,7 @@
SourceLocation getEndLoc() const { return EndLoc; }
void setEndLoc(SourceLocation L) { EndLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(StartLoc, EndLoc);
}
@@ -524,7 +525,7 @@
bool hasLeadingEmptyMacro() const { return HasLeadingEmptyMacro; }
- SourceRange getSourceRange() const { return SourceRange(SemiLoc); }
+ SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(SemiLoc); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == NullStmtClass;
@@ -604,7 +605,7 @@
return const_reverse_body_iterator(body_begin());
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(LBracLoc, RBracLoc);
}
@@ -649,7 +650,7 @@
return const_cast<SwitchCase*>(this)->getSubStmt();
}
- SourceRange getSourceRange() const { return SourceRange(); }
+ SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == CaseStmtClass ||
@@ -704,7 +705,7 @@
void setRHS(Expr *Val) { SubExprs[RHS] = reinterpret_cast<Stmt*>(Val); }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
// Handle deeply nested case statements with iteration instead of recursion.
const CaseStmt *CS = this;
while (const CaseStmt *CS2 = dyn_cast<CaseStmt>(CS->getSubStmt()))
@@ -744,7 +745,7 @@
SourceLocation getColonLoc() const { return ColonLoc; }
void setColonLoc(SourceLocation L) { ColonLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(DefaultLoc, SubStmt->getLocEnd());
}
static bool classof(const Stmt *T) {
@@ -781,7 +782,7 @@
void setIdentLoc(SourceLocation L) { IdentLoc = L; }
void setSubStmt(Stmt *SS) { SubStmt = SS; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(IdentLoc, SubStmt->getLocEnd());
}
child_range children() { return child_range(&SubStmt, &SubStmt+1); }
@@ -842,7 +843,7 @@
SourceLocation getElseLoc() const { return ElseLoc; }
void setElseLoc(SourceLocation L) { ElseLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
if (SubExprs[ELSE])
return SourceRange(IfLoc, SubExprs[ELSE]->getLocEnd());
else
@@ -941,7 +942,7 @@
return (bool) AllEnumCasesCovered;
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(SwitchLoc, SubExprs[BODY]->getLocEnd());
}
// Iterators
@@ -996,7 +997,7 @@
SourceLocation getWhileLoc() const { return WhileLoc; }
void setWhileLoc(SourceLocation L) { WhileLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(WhileLoc, SubExprs[BODY]->getLocEnd());
}
static bool classof(const Stmt *T) {
@@ -1045,7 +1046,7 @@
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(DoLoc, RParenLoc);
}
static bool classof(const Stmt *T) {
@@ -1117,7 +1118,7 @@
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
}
static bool classof(const Stmt *T) {
@@ -1152,7 +1153,7 @@
SourceLocation getLabelLoc() const { return LabelLoc; }
void setLabelLoc(SourceLocation L) { LabelLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(GotoLoc, LabelLoc);
}
static bool classof(const Stmt *T) {
@@ -1196,7 +1197,7 @@
return const_cast<IndirectGotoStmt*>(this)->getConstantTarget();
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(GotoLoc, Target->getLocEnd());
}
@@ -1223,7 +1224,7 @@
SourceLocation getContinueLoc() const { return ContinueLoc; }
void setContinueLoc(SourceLocation L) { ContinueLoc = L; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(ContinueLoc);
}
@@ -1249,7 +1250,7 @@
SourceLocation getBreakLoc() const { return BreakLoc; }
void setBreakLoc(SourceLocation L) { BreakLoc = L; }
- SourceRange getSourceRange() const { return SourceRange(BreakLoc); }
+ SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(BreakLoc); }
static bool classof(const Stmt *T) {
return T->getStmtClass() == BreakStmtClass;
@@ -1301,7 +1302,7 @@
const VarDecl *getNRVOCandidate() const { return NRVOCandidate; }
void setNRVOCandidate(const VarDecl *Var) { NRVOCandidate = Var; }
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == ReturnStmtClass;
@@ -1511,7 +1512,7 @@
StringLiteral *getClobber(unsigned i) { return Clobbers[i]; }
const StringLiteral *getClobber(unsigned i) const { return Clobbers[i]; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(AsmLoc, RParenLoc);
}
@@ -1582,7 +1583,7 @@
SourceLocation ExceptLoc,
Expr *FilterExpr,
Stmt *Block);
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getExceptLoc(), getEndLoc());
}
@@ -1625,7 +1626,7 @@
SourceLocation FinallyLoc,
Stmt *Block);
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getFinallyLoc(), getEndLoc());
}
@@ -1669,7 +1670,7 @@
Stmt *TryBlock,
Stmt *Handler);
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getTryLoc(), getEndLoc());
}
Modified: cfe/branches/tooling/include/clang/AST/StmtCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/StmtCXX.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/StmtCXX.h (original)
+++ cfe/branches/tooling/include/clang/AST/StmtCXX.h Mon Mar 19 14:02:20 2012
@@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_STMTCXX_H
#include "clang/AST/Stmt.h"
+#include "llvm/Support/Compiler.h"
namespace clang {
@@ -37,7 +38,7 @@
CXXCatchStmt(EmptyShell Empty)
: Stmt(CXXCatchStmtClass), ExceptionDecl(0), HandlerBlock(0) {}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(CatchLoc, HandlerBlock->getLocEnd());
}
@@ -83,7 +84,7 @@
static CXXTryStmt *Create(ASTContext &C, EmptyShell Empty,
unsigned numHandlers);
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getTryLoc(), getEndLoc());
}
@@ -189,7 +190,7 @@
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
}
static bool classof(const Stmt *T) {
@@ -274,7 +275,7 @@
return reinterpret_cast<CompoundStmt *>(SubStmt);
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(KeywordLoc, SubStmt->getLocEnd());
}
Modified: cfe/branches/tooling/include/clang/AST/StmtObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/StmtObjC.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/StmtObjC.h (original)
+++ cfe/branches/tooling/include/clang/AST/StmtObjC.h Mon Mar 19 14:02:20 2012
@@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_STMTOBJC_H
#include "clang/AST/Stmt.h"
+#include "llvm/Support/Compiler.h"
namespace clang {
@@ -55,7 +56,7 @@
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(ForLoc, SubExprs[BODY]->getLocEnd());
}
static bool classof(const Stmt *T) {
@@ -103,7 +104,7 @@
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(AtCatchLoc, Body->getLocEnd());
}
@@ -133,7 +134,7 @@
Stmt *getFinallyBody() { return AtFinallyStmt; }
void setFinallyBody(Stmt *S) { AtFinallyStmt = S; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(AtFinallyLoc, AtFinallyStmt->getLocEnd());
}
@@ -240,7 +241,7 @@
getStmts()[1 + NumCatchStmts] = S;
}
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCAtTryStmtClass;
@@ -294,7 +295,7 @@
}
void setSynchExpr(Stmt *S) { SubStmts[SYNC_EXPR] = S; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(AtSynchronizedLoc, getSynchBody()->getLocEnd());
}
@@ -327,7 +328,7 @@
SourceLocation getThrowLoc() { return AtThrowLoc; }
void setThrowLoc(SourceLocation Loc) { AtThrowLoc = Loc; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
if (Throw)
return SourceRange(AtThrowLoc, Throw->getLocEnd());
else
@@ -360,7 +361,7 @@
Stmt *getSubStmt() { return SubStmt; }
void setSubStmt(Stmt *S) { SubStmt = S; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(AtLoc, SubStmt->getLocEnd());
}
Modified: cfe/branches/tooling/include/clang/AST/TemplateBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/TemplateBase.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/TemplateBase.h (original)
+++ cfe/branches/tooling/include/clang/AST/TemplateBase.h Mon Mar 19 14:02:20 2012
@@ -15,11 +15,12 @@
#ifndef LLVM_CLANG_AST_TEMPLATEBASE_H
#define LLVM_CLANG_AST_TEMPLATEBASE_H
+#include "clang/AST/Type.h"
+#include "clang/AST/TemplateName.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/TemplateName.h"
namespace llvm {
class FoldingSetNodeID;
@@ -457,7 +458,7 @@
}
/// \brief - Fetches the full source range of the argument.
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
const TemplateArgument &getArgument() const {
return Argument;
Modified: cfe/branches/tooling/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/Type.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/Type.h (original)
+++ cfe/branches/tooling/include/clang/AST/Type.h Mon Mar 19 14:02:20 2012
@@ -4816,6 +4816,12 @@
return false;
}
+inline bool Type::isVoidType() const {
+ if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+ return BT->getKind() == BuiltinType::Void;
+ return false;
+}
+
inline bool Type::isHalfType() const {
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->getKind() == BuiltinType::Half;
Modified: cfe/branches/tooling/include/clang/AST/TypeLoc.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/TypeLoc.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/TypeLoc.h (original)
+++ cfe/branches/tooling/include/clang/AST/TypeLoc.h Mon Mar 19 14:02:20 2012
@@ -18,6 +18,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/TemplateBase.h"
#include "clang/Basic/Specifiers.h"
+#include "llvm/Support/Compiler.h"
namespace clang {
class ASTContext;
@@ -93,9 +94,11 @@
SourceLocation getEndLoc() const;
/// \brief Get the full source range.
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(getBeginLoc(), getEndLoc());
}
+ SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
/// \brief Get the local source range.
SourceRange getLocalSourceRange() const {
@@ -569,8 +572,9 @@
/// \brief True if the tag was defined in this type specifier.
bool isDefinition() const {
- return getDecl()->isCompleteDefinition() &&
- (getNameLoc().isInvalid() || getNameLoc() == getDecl()->getLocation());
+ TagDecl *D = getDecl();
+ return D->isCompleteDefinition() &&
+ (D->getIdentifier() == 0 || D->getLocation() == getNameLoc());
}
};
Modified: cfe/branches/tooling/include/clang/Analysis/Analyses/FormatString.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Analysis/Analyses/FormatString.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Analysis/Analyses/FormatString.h (original)
+++ cfe/branches/tooling/include/clang/Analysis/Analyses/FormatString.h Mon Mar 19 14:02:20 2012
@@ -306,9 +306,9 @@
LengthModifier LM;
OptionalAmount FieldWidth;
ConversionSpecifier CS;
- /// Positional arguments, an IEEE extension:
- /// IEEE Std 1003.1, 2004 Edition
- /// http://www.opengroup.org/onlinepubs/009695399/functions/printf.html
+ /// Positional arguments, an IEEE extension:
+ /// IEEE Std 1003.1, 2004 Edition
+ /// http://www.opengroup.org/onlinepubs/009695399/functions/printf.html
bool UsesPositionalArg;
unsigned argIndex;
public:
@@ -598,6 +598,8 @@
virtual void HandleNullChar(const char *nullCharacter) {}
+ virtual void HandlePosition(const char *startPos, unsigned posLen) {}
+
virtual void HandleInvalidPosition(const char *startPos, unsigned posLen,
PositionContext p) {}
Modified: cfe/branches/tooling/include/clang/Analysis/CallGraph.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Analysis/CallGraph.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Analysis/CallGraph.h (original)
+++ cfe/branches/tooling/include/clang/Analysis/CallGraph.h Mon Mar 19 14:02:20 2012
@@ -27,7 +27,7 @@
class CallGraph {
friend class CallGraphNode;
- typedef llvm::DenseMap<Decl *, CallGraphNode *> FunctionMapTy;
+ typedef llvm::DenseMap<const Decl *, CallGraphNode *> FunctionMapTy;
/// FunctionMap owns all CallGraphNodes.
FunctionMapTy FunctionMap;
@@ -48,8 +48,12 @@
/// \brief Add the given declaration to the call graph.
void addToCallGraph(Decl *D, bool IsGlobal);
- /// \brief Populate the call graph with the functions in the given DeclContext.
- void addToCallGraph(DeclContext *DC);
+ /// \brief Populate the call graph with the functions in the given translation
+ /// unit.
+ void addToCallGraph(TranslationUnitDecl *TU);
+
+ /// \brief Lookup the node for the given declaration.
+ CallGraphNode *getNode(const Decl *) const;
/// \brief Lookup the node for the given declaration. If none found, insert
/// one into the graph.
@@ -165,7 +169,7 @@
static NodeType *getEntryNode(clang::CallGraph *CGN) {
return CGN->getRoot(); // Start at the external node!
}
- typedef std::pair<clang::Decl*, clang::CallGraphNode*> PairTy;
+ typedef std::pair<const clang::Decl*, clang::CallGraphNode*> PairTy;
typedef std::pointer_to_unary_function<PairTy, clang::CallGraphNode&> DerefFun;
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
typedef mapped_iterator<clang::CallGraph::iterator, DerefFun> nodes_iterator;
@@ -190,7 +194,7 @@
static NodeType *getEntryNode(const clang::CallGraph *CGN) {
return CGN->getRoot();
}
- typedef std::pair<clang::Decl*, clang::CallGraphNode*> PairTy;
+ typedef std::pair<const clang::Decl*, clang::CallGraphNode*> PairTy;
typedef std::pointer_to_unary_function<PairTy, clang::CallGraphNode&> DerefFun;
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
typedef mapped_iterator<clang::CallGraph::const_iterator,
Modified: cfe/branches/tooling/include/clang/Analysis/DomainSpecific/CocoaConventions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Analysis/DomainSpecific/CocoaConventions.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Analysis/DomainSpecific/CocoaConventions.h (original)
+++ cfe/branches/tooling/include/clang/Analysis/DomainSpecific/CocoaConventions.h Mon Mar 19 14:02:20 2012
@@ -14,25 +14,15 @@
#ifndef LLVM_CLANG_ANALYSIS_DS_COCOA
#define LLVM_CLANG_ANALYSIS_DS_COCOA
-#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
namespace clang {
class FunctionDecl;
-class ObjCMethodDecl;
class QualType;
namespace ento {
namespace cocoa {
-
- enum NamingConvention { NoConvention, CreateRule, InitRule };
-
- NamingConvention deriveNamingConvention(Selector S, const ObjCMethodDecl *MD);
-
- static inline bool followsFundamentalRule(Selector S,
- const ObjCMethodDecl *MD) {
- return deriveNamingConvention(S, MD) == CreateRule;
- }
bool isRefType(QualType RetTy, StringRef Prefix,
StringRef Name = StringRef());
Modified: cfe/branches/tooling/include/clang/Basic/Builtins.def
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/Builtins.def?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/Builtins.def (original)
+++ cfe/branches/tooling/include/clang/Basic/Builtins.def Mon Mar 19 14:02:20 2012
@@ -452,12 +452,15 @@
// GCC Object size checking builtins
BUILTIN(__builtin_object_size, "zvC*i", "n")
BUILTIN(__builtin___memcpy_chk, "v*v*vC*zz", "nF")
+BUILTIN(__builtin___memccpy_chk, "v*v*vC*iz", "nF")
BUILTIN(__builtin___memmove_chk, "v*v*vC*zz", "nF")
BUILTIN(__builtin___mempcpy_chk, "v*v*vC*zz", "nF")
BUILTIN(__builtin___memset_chk, "v*v*izz", "nF")
BUILTIN(__builtin___stpcpy_chk, "c*c*cC*z", "nF")
BUILTIN(__builtin___strcat_chk, "c*c*cC*z", "nF")
BUILTIN(__builtin___strcpy_chk, "c*c*cC*z", "nF")
+BUILTIN(__builtin___strlcat_chk, "c*c*cC*zz", "nF")
+BUILTIN(__builtin___strlcpy_chk, "c*c*cC*zz", "nF")
BUILTIN(__builtin___strncat_chk, "c*c*cC*zz", "nF")
BUILTIN(__builtin___strncpy_chk, "c*c*cC*zz", "nF")
BUILTIN(__builtin___stpncpy_chk, "c*c*cC*zz", "nF")
Modified: cfe/branches/tooling/include/clang/Basic/ConvertUTF.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/ConvertUTF.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/ConvertUTF.h (original)
+++ cfe/branches/tooling/include/clang/Basic/ConvertUTF.h Mon Mar 19 14:02:20 2012
@@ -151,9 +151,11 @@
ConversionResult ConvertUTF32toUTF16 (
const UTF32** sourceStart, const UTF32* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
-#endif
Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
+#endif
+
+Boolean isLegalUTF8String(const UTF8 *source, const UTF8 *sourceEnd);
#ifdef __cplusplus
}
Modified: cfe/branches/tooling/include/clang/Basic/Diagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/Diagnostic.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/Diagnostic.h (original)
+++ cfe/branches/tooling/include/clang/Basic/Diagnostic.h Mon Mar 19 14:02:20 2012
@@ -636,13 +636,22 @@
/// MaxArguments - The maximum number of arguments we can hold. We currently
/// only support up to 10 arguments (%0-%9). A single diagnostic with more
/// than that almost certainly has to be simplified anyway.
- MaxArguments = 10
+ MaxArguments = 10,
+
+ /// MaxRanges - The maximum number of ranges we can hold.
+ MaxRanges = 10,
+
+ /// MaxFixItHints - The maximum number of ranges we can hold.
+ MaxFixItHints = 10
};
/// NumDiagArgs - This contains the number of entries in Arguments.
signed char NumDiagArgs;
- /// NumRanges - This is the number of ranges in the DiagRanges array.
+ /// NumDiagRanges - This is the number of ranges in the DiagRanges array.
unsigned char NumDiagRanges;
+ /// NumDiagFixItHints - This is the number of hints in the DiagFixItHints
+ /// array.
+ unsigned char NumDiagFixItHints;
/// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
/// values, with one for each argument. This specifies whether the argument
@@ -660,13 +669,12 @@
/// sort of argument kind it is.
intptr_t DiagArgumentsVal[MaxArguments];
- /// DiagRanges - The list of ranges added to this diagnostic. It currently
- /// only support 10 ranges, could easily be extended if needed.
- CharSourceRange DiagRanges[10];
-
- /// FixItHints - If valid, provides a hint with some code
- /// to insert, remove, or modify at a particular position.
- SmallVector<FixItHint, 6> FixItHints;
+ /// DiagRanges - The list of ranges added to this diagnostic.
+ CharSourceRange DiagRanges[MaxRanges];
+
+ /// FixItHints - If valid, provides a hint with some code to insert, remove,
+ /// or modify at a particular position.
+ FixItHint DiagFixItHints[MaxFixItHints];
DiagnosticMappingInfo makeMappingInfo(diag::Mapping Map, SourceLocation L) {
bool isPragma = L.isValid();
@@ -692,6 +700,24 @@
return Diags->ProcessDiag(*this);
}
+ /// @name Diagnostic Emission
+ /// @{
+protected:
+ // Sema requires access to the following functions because the current design
+ // of SFINAE requires it to use its own SemaDiagnosticBuilder, which needs to
+ // access us directly to ensure we minimize the emitted code for the common
+ // Sema::Diag() patterns.
+ friend class Sema;
+
+ /// \brief Emit the current diagnostic and clear the diagnostic state.
+ bool EmitCurrentDiagnostic();
+
+ unsigned getCurrentDiagID() const { return CurDiagID; }
+
+ SourceLocation getCurrentDiagLoc() const { return CurDiagLoc; }
+
+ /// @}
+
friend class ASTReader;
friend class ASTWriter;
};
@@ -744,38 +770,39 @@
/// for example.
class DiagnosticBuilder {
mutable DiagnosticsEngine *DiagObj;
- mutable unsigned NumArgs, NumRanges;
+ mutable unsigned NumArgs, NumRanges, NumFixits;
+
+ /// \brief Status variable indicating if this diagnostic is still active.
+ ///
+ // NOTE: This field is redundant with DiagObj (IsActive iff (DiagObj == 0)),
+ // but LLVM is not currently smart enough to eliminate the null check that
+ // Emit() would end up with if we used that as our status variable.
+ mutable bool IsActive;
void operator=(const DiagnosticBuilder&); // DO NOT IMPLEMENT
friend class DiagnosticsEngine;
explicit DiagnosticBuilder(DiagnosticsEngine *diagObj)
- : DiagObj(diagObj), NumArgs(0), NumRanges(0) {
- DiagObj->FixItHints.clear();
+ : DiagObj(diagObj), NumArgs(0), NumRanges(0), NumFixits(0), IsActive(true) {
+ assert(diagObj && "DiagnosticBuilder requires a valid DiagnosticsEngine!");
}
friend class PartialDiagnostic;
protected:
- void FlushCounts();
-
-public:
- /// Copy constructor. When copied, this "takes" the diagnostic info from the
- /// input and neuters it.
- DiagnosticBuilder(const DiagnosticBuilder &D) {
- DiagObj = D.DiagObj;
- D.DiagObj = 0;
- NumArgs = D.NumArgs;
- NumRanges = D.NumRanges;
+ void FlushCounts() {
+ DiagObj->NumDiagArgs = NumArgs;
+ DiagObj->NumDiagRanges = NumRanges;
+ DiagObj->NumDiagFixItHints = NumFixits;
+ }
+
+ /// \brief Clear out the current diagnostic.
+ void Clear() const {
+ DiagObj = 0;
+ IsActive = false;
}
- /// \brief Simple enumeration value used to give a name to the
- /// suppress-diagnostic constructor.
- enum SuppressKind { Suppress };
-
- /// \brief Create an empty DiagnosticBuilder object that represents
- /// no actual diagnostic.
- explicit DiagnosticBuilder(SuppressKind)
- : DiagObj(0), NumArgs(0), NumRanges(0) { }
+ /// isActive - Determine whether this diagnostic is still active.
+ bool isActive() const { return IsActive; }
/// \brief Force the diagnostic builder to emit the diagnostic now.
///
@@ -784,30 +811,40 @@
///
/// \returns true if a diagnostic was emitted, false if the
/// diagnostic was suppressed.
- bool Emit();
+ bool Emit() {
+ // If this diagnostic is inactive, then its soul was stolen by the copy ctor
+ // (or by a subclass, as in SemaDiagnosticBuilder).
+ if (!isActive()) return false;
+
+ // When emitting diagnostics, we set the final argument count into
+ // the DiagnosticsEngine object.
+ FlushCounts();
- /// Destructor - The dtor emits the diagnostic if it hasn't already
- /// been emitted.
- ~DiagnosticBuilder() { Emit(); }
+ // Process the diagnostic.
+ bool Result = DiagObj->EmitCurrentDiagnostic();
- /// isActive - Determine whether this diagnostic is still active.
- bool isActive() const { return DiagObj != 0; }
+ // This diagnostic is dead.
+ Clear();
- /// \brief Retrieve the active diagnostic ID.
- ///
- /// \pre \c isActive()
- unsigned getDiagID() const {
- assert(isActive() && "DiagnosticsEngine is inactive");
- return DiagObj->CurDiagID;
+ return Result;
}
-
- /// \brief Retrieve the active diagnostic's location.
- ///
- /// \pre \c isActive()
- SourceLocation getLocation() const { return DiagObj->CurDiagLoc; }
- /// \brief Clear out the current diagnostic.
- void Clear() { DiagObj = 0; }
+public:
+ /// Copy constructor. When copied, this "takes" the diagnostic info from the
+ /// input and neuters it.
+ DiagnosticBuilder(const DiagnosticBuilder &D) {
+ DiagObj = D.DiagObj;
+ IsActive = D.IsActive;
+ D.Clear();
+ NumArgs = D.NumArgs;
+ NumRanges = D.NumRanges;
+ NumFixits = D.NumFixits;
+ }
+
+ /// Destructor - The dtor emits the diagnostic.
+ ~DiagnosticBuilder() {
+ Emit();
+ }
/// Operator bool: conversion of DiagnosticBuilder to bool always returns
/// true. This allows is to be used in boolean error contexts like:
@@ -815,34 +852,33 @@
operator bool() const { return true; }
void AddString(StringRef S) const {
+ assert(isActive() && "Clients must not add to cleared diagnostic!");
assert(NumArgs < DiagnosticsEngine::MaxArguments &&
"Too many arguments to diagnostic!");
- if (DiagObj) {
- DiagObj->DiagArgumentsKind[NumArgs] = DiagnosticsEngine::ak_std_string;
- DiagObj->DiagArgumentsStr[NumArgs++] = S;
- }
+ DiagObj->DiagArgumentsKind[NumArgs] = DiagnosticsEngine::ak_std_string;
+ DiagObj->DiagArgumentsStr[NumArgs++] = S;
}
void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const {
+ assert(isActive() && "Clients must not add to cleared diagnostic!");
assert(NumArgs < DiagnosticsEngine::MaxArguments &&
"Too many arguments to diagnostic!");
- if (DiagObj) {
- DiagObj->DiagArgumentsKind[NumArgs] = Kind;
- DiagObj->DiagArgumentsVal[NumArgs++] = V;
- }
+ DiagObj->DiagArgumentsKind[NumArgs] = Kind;
+ DiagObj->DiagArgumentsVal[NumArgs++] = V;
}
void AddSourceRange(const CharSourceRange &R) const {
- assert(NumRanges <
- sizeof(DiagObj->DiagRanges)/sizeof(DiagObj->DiagRanges[0]) &&
+ assert(isActive() && "Clients must not add to cleared diagnostic!");
+ assert(NumRanges < DiagnosticsEngine::MaxRanges &&
"Too many arguments to diagnostic!");
- if (DiagObj)
- DiagObj->DiagRanges[NumRanges++] = R;
+ DiagObj->DiagRanges[NumRanges++] = R;
}
void AddFixItHint(const FixItHint &Hint) const {
- if (DiagObj)
- DiagObj->FixItHints.push_back(Hint);
+ assert(isActive() && "Clients must not add to cleared diagnostic!");
+ assert(NumFixits < DiagnosticsEngine::MaxFixItHints &&
+ "Too many arguments to diagnostic!");
+ DiagObj->DiagFixItHints[NumFixits++] = Hint;
}
};
@@ -1018,16 +1054,16 @@
}
unsigned getNumFixItHints() const {
- return DiagObj->FixItHints.size();
+ return DiagObj->NumDiagFixItHints;
}
const FixItHint &getFixItHint(unsigned Idx) const {
- return DiagObj->FixItHints[Idx];
+ assert(Idx < getNumFixItHints() && "Invalid index!");
+ return DiagObj->DiagFixItHints[Idx];
}
const FixItHint *getFixItHints() const {
- return getNumFixItHints()?
- DiagObj->FixItHints.data() : 0;
+ return getNumFixItHints()? DiagObj->DiagFixItHints : 0;
}
/// FormatDiagnostic - Format this diagnostic into a string, substituting the
Modified: cfe/branches/tooling/include/clang/Basic/DiagnosticASTKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/DiagnosticASTKinds.td?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticASTKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticASTKinds.td Mon Mar 19 14:02:20 2012
@@ -107,11 +107,6 @@
"see all)">;
def note_constexpr_call_here : Note<"in call to '%0'">;
-// FIXME: See EvalInfo::IntExprEvaluatorDepth.
-def err_intexpr_depth_limit_exceeded : Error<
- "integer expression evaluation exceeded maximum sub-expression depth">,
- DefaultFatal; // avoid emitting it multiple times for the same parent expr.
-
// inline asm related.
let CategoryName = "Inline Assembly Issue" in {
def err_asm_invalid_escape : Error<
Modified: cfe/branches/tooling/include/clang/Basic/DiagnosticCommonKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/DiagnosticCommonKinds.td?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticCommonKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticCommonKinds.td Mon Mar 19 14:02:20 2012
@@ -43,6 +43,10 @@
"must end with ':'">;
def err_invalid_string_udl : Error<
"string literal with user-defined suffix cannot be used here">;
+def err_invalid_character_udl : Error<
+ "character literal with user-defined suffix cannot be used here">;
+def err_invalid_numeric_udl : Error<
+ "numeric literal with user-defined suffix cannot be used here">;
// Parse && Sema
def ext_no_declarators : ExtWarn<"declaration does not declare anything">,
Modified: cfe/branches/tooling/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/DiagnosticGroups.td?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticGroups.td Mon Mar 19 14:02:20 2012
@@ -26,8 +26,13 @@
def : DiagGroup<"bad-function-cast">;
def Availability : DiagGroup<"availability">;
def AutoImport : DiagGroup<"auto-import">;
-def BoolConversions : DiagGroup<"bool-conversions">;
-def IntConversions : DiagGroup<"int-conversions">;
+def ConstantConversion : DiagGroup<"constant-conversion">;
+def LiteralConversion : DiagGroup<"literal-conversion">;
+def StringConversion : DiagGroup<"string-conversion">;
+def SignConversion : DiagGroup<"sign-conversion">;
+def BoolConversion : DiagGroup<"bool-conversion">;
+def IntConversion : DiagGroup<"int-conversion">;
+def NullConversion : DiagGroup<"null-conversion">;
def BuiltinRequiresHeader : DiagGroup<"builtin-requires-header">;
def CXXCompat: DiagGroup<"c++-compat">;
def CastAlign : DiagGroup<"cast-align">;
@@ -250,7 +255,7 @@
def OverridingMethodMismatch : DiagGroup<"overriding-method-mismatch">;
def : DiagGroup<"variadic-macros">;
def VariadicMacros : DiagGroup<"variadic-macros">;
-def VectorConversions : DiagGroup<"vector-conversions">; // clang specific
+def VectorConversion : DiagGroup<"vector-conversion">; // clang specific
def VexingParse : DiagGroup<"vexing-parse">;
def VLA : DiagGroup<"vla">;
def VolatileRegisterVar : DiagGroup<"volatile-register-var">;
@@ -282,14 +287,16 @@
// - conversion warnings with constant sources are on by default
// - conversion warnings for literals are on by default
// - bool-to-pointer conversion warnings are on by default
+// - __null-to-integer conversion warnings are on by default
def Conversion : DiagGroup<"conversion",
[DiagGroup<"shorten-64-to-32">,
- DiagGroup<"constant-conversion">,
- DiagGroup<"literal-conversion">,
- DiagGroup<"string-conversion">,
- DiagGroup<"sign-conversion">,
- BoolConversions,
- IntConversions]>,
+ ConstantConversion,
+ LiteralConversion,
+ StringConversion,
+ SignConversion,
+ BoolConversion,
+ NullConversion,
+ IntConversion]>,
DiagCategory<"Value Conversion Issue">;
def Unused : DiagGroup<"unused",
@@ -302,7 +309,7 @@
// Format settings.
def FormatInvalidSpecifier : DiagGroup<"format-invalid-specifier">;
def FormatSecurity : DiagGroup<"format-security">;
-def FormatNonStandard : DiagGroup<"format-non-standard">;
+def FormatNonStandard : DiagGroup<"format-non-iso">;
def FormatY2K : DiagGroup<"format-y2k">;
def Format : DiagGroup<"format",
[FormatExtraArgs, FormatZeroLength, NonNull,
@@ -357,6 +364,14 @@
def : DiagGroup<"", [Extra]>; // -W = -Wextra
def : DiagGroup<"endif-labels", [ExtraTokens]>; // -Wendif-labels=-Wendif-tokens
def : DiagGroup<"comments", [Comment]>; // -Wcomments = -Wcomment
+def : DiagGroup<"conversion-null",
+ [NullConversion]>; // -Wconversion-null = -Wnull-conversion
+def : DiagGroup<"bool-conversions",
+ [BoolConversion]>; // -Wbool-conversions = -Wbool-conversion
+def : DiagGroup<"int-conversions",
+ [IntConversion]>; // -Wint-conversions = -Wint-conversion
+def : DiagGroup<"vector-conversions",
+ [VectorConversion]>; // -Wvector-conversions = -Wvector-conversion
// A warning group for warnings that we want to have on by default in clang,
// but which aren't on by default in GCC.
Modified: cfe/branches/tooling/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/DiagnosticLexKinds.td?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticLexKinds.td Mon Mar 19 14:02:20 2012
@@ -95,6 +95,16 @@
def err_ucn_escape_no_digits : Error<"\\u used with no following hex digits">;
def err_ucn_escape_invalid : Error<"invalid universal character">;
def err_ucn_escape_incomplete : Error<"incomplete universal character name">;
+def err_ucn_escape_basic_scs : Error<
+ "character '%0' cannot be specified by a universal character name">;
+def err_ucn_control_character : Error<
+ "universal character name refers to a control character">;
+def warn_cxx98_compat_literal_ucn_escape_basic_scs : Warning<
+ "specifying character '%0' with a universal character name "
+ "is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
+def warn_cxx98_compat_literal_ucn_control_character : Warning<
+ "universal character name referring to a control character "
+ "is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
def err_invalid_decimal_digit : Error<"invalid digit '%0' in decimal constant">;
def err_invalid_binary_digit : Error<"invalid digit '%0' in binary constant">;
def err_invalid_octal_digit : Error<"invalid digit '%0' in octal constant">;
@@ -216,7 +226,11 @@
def warn_pp_convert_rhs_to_positive : Warning<
"right side of operator converted from negative value to unsigned: %0">;
-def ext_pp_import_directive : Extension<"#import is a language extension">;
+def ext_pp_import_directive : Extension<"#import is a language extension">,
+ InGroup<DiagGroup<"import-preprocessor-directive-pedantic">>;
+def err_pp_import_directive_ms : Error<
+ "#import of type library is an unsupported Microsoft feature">;
+
def ext_pp_ident_directive : Extension<"#ident is a language extension">;
def ext_pp_include_next_directive : Extension<
"#include_next is a language extension">;
Modified: cfe/branches/tooling/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/DiagnosticParseKinds.td?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticParseKinds.td Mon Mar 19 14:02:20 2012
@@ -56,6 +56,8 @@
"variable declaration in for loop is a C99-specific feature">, InGroup<C99>;
def ext_c99_compound_literal : Extension<
"compound literals are a C99-specific feature">, InGroup<C99>;
+def ext_c99_flexible_array_member : Extension<
+ "Flexible array members are a C99-specific feature">, InGroup<C99>;
def ext_enumerator_list_comma : Extension<
"commas at the end of enumerator lists are a %select{C99|C++11}0-specific "
"feature">;
@@ -280,9 +282,11 @@
"type name does not allow storage class to be specified">;
def err_typename_invalid_functionspec : Error<
"type name does not allow function specifier to be specified">;
+def err_typename_invalid_constexpr : Error<
+ "type name does not allow constexpr specifier to be specified">;
def err_typename_identifiers_only : Error<
"typename is allowed for identifiers only">;
-
+
def err_invalid_decl_spec_combination : Error<
"cannot combine with previous '%0' declaration specifier">;
def err_invalid_vector_decl_spec_combination : Error<
@@ -429,6 +433,8 @@
def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;
// C++ operator overloading
+def err_literal_operator_string_prefix : Error<
+ "string literal after 'operator' cannot have an encoding prefix">;
def err_literal_operator_string_not_empty : Error<
"string literal after 'operator' must be '\"\"'">;
def err_literal_operator_missing_space : Error<
Modified: cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td Mon Mar 19 14:02:20 2012
@@ -1569,16 +1569,15 @@
def warn_attribute_wrong_decl_type : Warning<
"%0 attribute only applies to %select{functions|unions|"
"variables and functions|functions and methods|parameters|"
- "parameters and methods|functions, methods and blocks|"
- "classes and virtual methods|functions, methods, and parameters|"
- "classes|virtual methods|class members|variables|methods|"
- "variables, functions and labels|fields and global variables}1">;
+ "functions, methods and blocks|functions, methods, and parameters|"
+ "classes|variables|methods|variables, functions and labels|"
+ "fields and global variables|structs}1">;
def err_attribute_wrong_decl_type : Error<
"%0 attribute only applies to %select{functions|unions|"
"variables and functions|functions and methods|parameters|"
- "parameters and methods|functions, methods and blocks|"
- "classes and virtual methods|functions, methods, and parameters|"
- "classes|virtual methods|class members|variables|methods|structs}1">;
+ "functions, methods and blocks|functions, methods, and parameters|"
+ "classes|variables|methods|variables, functions and labels|"
+ "fields and global variables|structs}1">;
def warn_function_attribute_wrong_type : Warning<
"'%0' only applies to function types; type here is %1">;
def warn_pointer_attribute_wrong_type : Warning<
@@ -1702,10 +1701,10 @@
InGroup<DiagGroup<"conversion">>, DefaultIgnore;
def warn_impcast_integer_sign : Warning<
"implicit conversion changes signedness: %0 to %1">,
- InGroup<DiagGroup<"sign-conversion">>, DefaultIgnore;
+ InGroup<SignConversion>, DefaultIgnore;
def warn_impcast_integer_sign_conditional : Warning<
"operand of ? changes signedness: %0 to %1">,
- InGroup<DiagGroup<"sign-conversion">>, DefaultIgnore;
+ InGroup<SignConversion>, DefaultIgnore;
def warn_impcast_integer_precision : Warning<
"implicit conversion loses integer precision: %0 to %1">,
InGroup<DiagGroup<"conversion">>, DefaultIgnore;
@@ -1714,29 +1713,29 @@
InGroup<DiagGroup<"shorten-64-to-32">>, DefaultIgnore;
def warn_impcast_integer_precision_constant : Warning<
"implicit conversion from %2 to %3 changes value from %0 to %1">,
- InGroup<DiagGroup<"constant-conversion">>;
+ InGroup<ConstantConversion>;
def warn_impcast_bitfield_precision_constant : Warning<
"implicit truncation from %2 to bitfield changes value from %0 to %1">,
- InGroup<DiagGroup<"constant-conversion">>;
+ InGroup<ConstantConversion>;
def warn_impcast_literal_float_to_integer : Warning<
"implicit conversion turns literal floating-point number into integer: "
"%0 to %1">,
- InGroup<DiagGroup<"literal-conversion">>, DefaultIgnore;
+ InGroup<LiteralConversion>, DefaultIgnore;
def warn_impcast_string_literal_to_bool : Warning<
"implicit conversion turns string literal into bool: %0 to %1">,
- InGroup<DiagGroup<"string-conversion">>, DefaultIgnore;
+ InGroup<StringConversion>, DefaultIgnore;
def warn_impcast_different_enum_types : Warning<
"implicit conversion from enumeration type %0 to different enumeration type "
"%1">, InGroup<DiagGroup<"conversion">>;
def warn_impcast_bool_to_null_pointer : Warning<
"initialization of pointer of type %0 to null from a constant boolean "
- "expression">, InGroup<BoolConversions>;
+ "expression">, InGroup<BoolConversion>;
def warn_impcast_null_pointer_to_integer : Warning<
- "implicit conversion of NULL constant to integer">,
- InGroup<DiagGroup<"conversion">>, DefaultIgnore;
+ "implicit conversion of NULL constant to %0">,
+ InGroup<NullConversion>;
def warn_impcast_function_to_bool : Warning<
"address of function %q0 will always evaluate to 'true'">,
- InGroup<BoolConversions>;
+ InGroup<BoolConversion>;
def note_function_to_bool_silence : Note<
"prefix with the address-of operator to silence this warning">;
def note_function_to_bool_call : Note<
@@ -2195,7 +2194,13 @@
"address of overloaded function %0 cannot be converted to type %1">;
def err_addr_ovl_no_qualifier : Error<
"can't form member pointer of type %0 without '&' and class name">;
-
+
+// C++11 Literal Operators
+def err_ovl_no_viable_literal_operator : Error<
+ "no matching literal operator for call to %0"
+ "%select{| with argument of type %2| with arguments of types %2 and %3}1"
+ "%select{| or 'const char *', and no matching literal operator template}4">;
+
// C++ Template Declarations
def err_template_param_shadow : Error<
"declaration of %0 shadows template parameter">;
@@ -2524,6 +2529,8 @@
"in instantiation of function template specialization %q0 requested here">;
def note_template_static_data_member_def_here : Note<
"in instantiation of static data member %q0 requested here">;
+def note_template_enum_def_here : Note<
+ "in instantiation of enumeration %q0 requested here">;
def note_template_type_alias_instantiation_here : Note<
"in instantiation of template type alias %0 requested here">;
@@ -3026,7 +3033,7 @@
"size of anonymous bit-field (%0 bits) exceeds size of its type (%1 bits)">;
def err_incorrect_number_of_vector_initializers : Error<
"number of elements must be either one or match the size of the vector">;
-
+
// Used by C++ which allows bit-fields that are wider than the type.
def warn_bitfield_width_exceeds_type_size: Warning<
"size of bit-field %0 (%1 bits) exceeds the size of its type; value will be "
@@ -4276,7 +4283,7 @@
"take the address with &|"
"remove *|"
"remove &}3">,
- InGroup<IntConversions>;
+ InGroup<IntConversion>;
def ext_typecheck_convert_int_pointer : ExtWarn<
"incompatible integer to pointer conversion "
"%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
@@ -4287,7 +4294,7 @@
"take the address with &|"
"remove *|"
"remove &}3">,
- InGroup<IntConversions>;
+ InGroup<IntConversion>;
def ext_typecheck_convert_pointer_void_func : Extension<
"%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
" %0 "
@@ -4332,7 +4339,7 @@
" %0 "
"%select{from|to parameter of type|from a function with result type|to type|"
"with an expression of type|to parameter of type|to type}2 %1">,
- InGroup<VectorConversions>, DefaultIgnore;
+ InGroup<VectorConversion>, DefaultIgnore;
def err_int_to_block_pointer : Error<
"invalid block pointer conversion "
"%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
@@ -4381,6 +4388,8 @@
"vector is not assignable (contains duplicate components)">;
def err_block_decl_ref_not_modifiable_lvalue : Error<
"variable is not assignable (missing __block type specifier)">;
+def err_lambda_decl_ref_not_modifiable_lvalue : Error<
+ "cannot assign to a variable captured by copy in a non-mutable lambda">;
def err_typecheck_call_not_function : Error<
"called object type %0 is not a function or function pointer">;
def err_call_incomplete_return : Error<
@@ -4752,6 +4761,8 @@
// C++ literal operators
def err_literal_operator_outside_namespace : Error<
"literal operator %0 must be in a namespace or global scope">;
+def err_literal_operator_default_argument : Error<
+ "literal operator cannot have a default argument">;
// FIXME: This diagnostic sucks
def err_literal_operator_params : Error<
"parameter declaration for literal operator %0 is not valid">;
@@ -4936,10 +4947,13 @@
def warn_format_nonsensical_length: Warning<
"length modifier '%0' results in undefined behavior or no effect with '%1' conversion specifier">,
InGroup<Format>;
+def warn_format_non_standard_positional_arg: ExtWarn<
+ "positional arguments are not supported by ISO C">, InGroup<FormatNonStandard>, DefaultIgnore;
def warn_format_non_standard: ExtWarn<
- "'%0' is a non-standard %1">, InGroup<FormatNonStandard>, DefaultIgnore;
+ "'%0' %select{length modifier|conversion specifier}1 is not supported by ISO C">,
+ InGroup<FormatNonStandard>, DefaultIgnore;
def warn_format_non_standard_conversion_spec: ExtWarn<
- "using the length modifier '%0' with the conversion specifier '%1' is non-standard">,
+ "using length modifier '%0' with conversion specifier '%1' is not supported by ISO C">,
InGroup<FormatNonStandard>, DefaultIgnore;
def warn_printf_ignored_flag: Warning<
"flag '%0' is ignored when flag '%1' is present">,
@@ -5083,7 +5097,7 @@
"default label in switch which covers all enumeration values">,
InGroup<CoveredSwitchDefault>, DefaultIgnore;
def warn_not_in_enum : Warning<"case value not in enumerated type %0">,
- InGroup<Switch>;
+ InGroup<Switch>;
def err_typecheck_statement_requires_scalar : Error<
"statement requires expression of scalar type (%0 invalid)">;
def err_typecheck_statement_requires_integer : Error<
Modified: cfe/branches/tooling/include/clang/Basic/LangOptions.def
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/LangOptions.def?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/LangOptions.def (original)
+++ cfe/branches/tooling/include/clang/Basic/LangOptions.def Mon Mar 19 14:02:20 2012
@@ -98,7 +98,7 @@
"default struct packing maximum alignment")
VALUE_LANGOPT(PICLevel , 2, 0, "__PIC__ level")
LANGOPT(GNUInline , 1, 0, "GNU inline semantics")
-LANGOPT(NoInline , 1, 0, "__NO_INLINE__ predefined macro")
+LANGOPT(NoInlineDefine , 1, 0, "__NO_INLINE__ predefined macro")
LANGOPT(Deprecated , 1, 0, "__DEPRECATED predefined macro")
LANGOPT(FastMath , 1, 0, "__FAST_MATH__ predefined macro")
Modified: cfe/branches/tooling/include/clang/Basic/Linkage.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/Linkage.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/Linkage.h (original)
+++ cfe/branches/tooling/include/clang/Basic/Linkage.h Mon Mar 19 14:02:20 2012
@@ -29,7 +29,7 @@
InternalLinkage,
/// \brief External linkage within a unique namespace. From the
- /// langauge perspective, these entities have external
+ /// language perspective, these entities have external
/// linkage. However, since they reside in an anonymous namespace,
/// their names are unique to this translation unit, which is
/// equivalent to having internal linkage from the code-generation
Modified: cfe/branches/tooling/include/clang/Basic/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/Makefile?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/Makefile (original)
+++ cfe/branches/tooling/include/clang/Basic/Makefile Mon Mar 19 14:02:20 2012
@@ -30,7 +30,7 @@
CLANG_HAS_VERSION_PATCHLEVEL := 1
endif
-$(ObjDir)/Diagnostic%Kinds.inc.tmp : Diagnostic.td Diagnostic%Kinds.td $(CLANG_TBLGEN) $(ObjDir)/.dir
+$(ObjDir)/Diagnostic%Kinds.inc.tmp : Diagnostic.td $(INPUT_TDS) $(CLANG_TBLGEN) $(ObjDir)/.dir
$(Echo) "Building Clang $(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) diagnostic tables with tblgen"
$(Verb) $(ClangTableGen) -gen-clang-diags-defs -clang-component=$(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) -o $(call SYSPATH, $@) $<
Modified: cfe/branches/tooling/include/clang/Basic/StmtNodes.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/StmtNodes.td?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/StmtNodes.td (original)
+++ cfe/branches/tooling/include/clang/Basic/StmtNodes.td Mon Mar 19 14:02:20 2012
@@ -156,7 +156,6 @@
// Clang Extensions.
def ShuffleVectorExpr : DStmt<Expr>;
def BlockExpr : DStmt<Expr>;
-def BlockDeclRefExpr : DStmt<Expr>;
def OpaqueValueExpr : DStmt<Expr>;
// Microsoft Extensions.
Modified: cfe/branches/tooling/include/clang/Driver/ArgList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Driver/ArgList.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Driver/ArgList.h (original)
+++ cfe/branches/tooling/include/clang/Driver/ArgList.h Mon Mar 19 14:02:20 2012
@@ -205,9 +205,17 @@
StringRef Default = "") const;
/// getLastArgValue - Return the value of the last argument as an integer,
+ /// or a default. If Diags is non-null, emits an error if the argument
+ /// is given, but non-integral.
+ int getLastArgIntValue(OptSpecifier Id, int Default,
+ DiagnosticsEngine *Diags = 0) const;
+
+ /// getLastArgValue - Return the value of the last argument as an integer,
/// or a default. Emits an error if the argument is given, but non-integral.
int getLastArgIntValue(OptSpecifier Id, int Default,
- DiagnosticsEngine &Diags) const;
+ DiagnosticsEngine &Diags) const {
+ return getLastArgIntValue(Id, Default, &Diags);
+ }
/// getAllArgValues - Get the values of all instances of the given argument
/// as strings.
Modified: cfe/branches/tooling/include/clang/Driver/CC1Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Driver/CC1Options.td?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Driver/CC1Options.td (original)
+++ cfe/branches/tooling/include/clang/Driver/CC1Options.td Mon Mar 19 14:02:20 2012
@@ -80,12 +80,25 @@
HelpText<"Display exploded graph using GraphViz">;
def analyzer_viz_egraph_ubigraph : Flag<"-analyzer-viz-egraph-ubigraph">,
HelpText<"Display exploded graph using Ubigraph">;
-def analyzer_inline_call : Flag<"-analyzer-inline-call">,
- HelpText<"Experimental: Inline callees when their definitions are available">;
+
def analyzer_inline_max_stack_depth : Separate<"-analyzer-inline-max-stack-depth">,
HelpText<"Bound on stack depth while inlining (4 by default)">;
+def analyzer_inline_max_stack_depth_EQ : Joined<"-analyzer-inline-max-stack-depth=">,
+ Alias<analyzer_inline_max_stack_depth>;
+
def analyzer_inline_max_function_size : Separate<"-analyzer-inline-max-function-size">,
HelpText<"Bound on the number of basic blocks in an inlined function (200 by default)">;
+def analyzer_inline_max_function_size_EQ : Joined<"-analyzer-inline-max-function-size=">,
+ Alias<analyzer_inline_max_function_size>;
+
+def analyzer_ipa : Separate<"-analyzer-ipa">,
+ HelpText<"Specify the inter-procedural analysis mode">;
+def analyzer_ipa_EQ : Joined<"-analyzer-ipa=">, Alias<analyzer_ipa>;
+
+def analyzer_inlining_mode : Separate<"-analyzer-inlining-mode">,
+ HelpText<"Specify the function selection heuristic used during inlining">;
+def analyzer_inlining_mode_EQ : Joined<"-analyzer-inlining-mode=">, Alias<analyzer_inlining_mode>;
+
def analyzer_max_nodes : Separate<"-analyzer-max-nodes">,
HelpText<"The maximum number of nodes the analyzer can generate (150000 default, 0 = no limit)">;
def analyzer_max_loop : Separate<"-analyzer-max-loop">,
@@ -503,6 +516,8 @@
HelpText<"Allow GNU-extension keywords regardless of language standard">;
def fgnu89_inline : Flag<"-fgnu89-inline">,
HelpText<"Use the gnu89 inline semantics">;
+def fno_inline : Flag<"-fno-inline">,
+ HelpText<"Disable use of the inline keyword">;
def fno_inline_functions : Flag<"-fno-inline-functions">,
HelpText<"Disable automatic function inlining">;
def fno_gnu_keywords : Flag<"-fno-gnu-keywords">,
Modified: cfe/branches/tooling/include/clang/Driver/Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Driver/Options.td?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Driver/Options.td (original)
+++ cfe/branches/tooling/include/clang/Driver/Options.td Mon Mar 19 14:02:20 2012
@@ -420,7 +420,7 @@
def fno_exceptions : Flag<"-fno-exceptions">, Group<f_Group>;
def fno_gnu_keywords : Flag<"-fno-gnu-keywords">, Group<f_Group>;
def fno_inline_functions : Flag<"-fno-inline-functions">, Group<f_Group>;
-def fno_inline : Flag<"-fno-inline">, Group<clang_ignored_f_Group>;
+def fno_inline : Flag<"-fno-inline">, Group<f_Group>;
def fno_keep_inline_functions : Flag<"-fno-keep-inline-functions">, Group<clang_ignored_f_Group>;
def fno_lax_vector_conversions : Flag<"-fno-lax-vector-conversions">, Group<f_Group>;
def fno_limit_debug_info : Flag<"-fno-limit-debug-info">, Group<f_Group>,
Modified: cfe/branches/tooling/include/clang/Edit/EditedSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Edit/EditedSource.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Edit/EditedSource.h (original)
+++ cfe/branches/tooling/include/clang/Edit/EditedSource.h Mon Mar 19 14:02:20 2012
@@ -50,7 +50,7 @@
StrAlloc(/*size=*/512) { }
const SourceManager &getSourceManager() const { return SourceMgr; }
- const LangOptions &getLangOptions() const { return LangOpts; }
+ const LangOptions &getLangOpts() const { return LangOpts; }
const PreprocessingRecord *getPreprocessingRecord() const { return PPRec; }
bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs);
Modified: cfe/branches/tooling/include/clang/Frontend/Analyses.def
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Frontend/Analyses.def?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Frontend/Analyses.def (original)
+++ cfe/branches/tooling/include/clang/Frontend/Analyses.def Mon Mar 19 14:02:20 2012
@@ -30,6 +30,7 @@
ANALYSIS_DIAGNOSTICS(HTML, "html", "Output analysis results using HTML", createHTMLDiagnosticConsumer, false)
ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", createPlistDiagnosticConsumer, true)
+ANALYSIS_DIAGNOSTICS(PLIST_MULTI_FILE, "plist-multi-file", "Output analysis results using Plists (allowing for mult-file bugs)", createPlistMultiFileDiagnosticConsumer, true)
ANALYSIS_DIAGNOSTICS(PLIST_HTML, "plist-html", "Output analysis results using HTML wrapped with Plists", createPlistHTMLDiagnosticConsumer, true)
ANALYSIS_DIAGNOSTICS(TEXT, "text", "Text output of analysis results", createTextPathDiagnosticConsumer, true)
@@ -41,8 +42,24 @@
ANALYSIS_PURGE(PurgeBlock, "block", "Purge symbols, bindings, and constraints before every basic block")
ANALYSIS_PURGE(PurgeNone, "none", "Do not purge symbols, bindings, or constraints")
+#ifndef ANALYSIS_IPA
+#define ANALYSIS_IPA(NAME, CMDFLAG, DESC)
+#endif
+
+ANALYSIS_IPA(None, "none", "Perform only intra-procedural analysis")
+ANALYSIS_IPA(Inlining, "inlining", "Experimental: Inline callees when their definitions are available")
+
+#ifndef ANALYSIS_INLINING_MODE
+#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC)
+#endif
+
+ANALYSIS_INLINING_MODE(All, "all", "Analyze all functions in the order defined in the TU")
+ANALYSIS_INLINING_MODE(NoRedundancy, "noredundancy", "Do not analyze a function which has been previously inlined, use call graph to order")
+
#undef ANALYSIS_STORE
#undef ANALYSIS_CONSTRAINTS
#undef ANALYSIS_DIAGNOSTICS
#undef ANALYSIS_PURGE
+#undef ANALYSIS_INLINING_MODE
+#undef ANALYSIS_IPA
Modified: cfe/branches/tooling/include/clang/Frontend/AnalyzerOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Frontend/AnalyzerOptions.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Frontend/AnalyzerOptions.h (original)
+++ cfe/branches/tooling/include/clang/Frontend/AnalyzerOptions.h Mon Mar 19 14:02:20 2012
@@ -60,6 +60,20 @@
NumPurgeModes
};
+/// AnalysisIPAMode - Set of inter-procedural modes.
+enum AnalysisIPAMode {
+#define ANALYSIS_IPA(NAME, CMDFLAG, DESC) NAME,
+#include "clang/Frontend/Analyses.def"
+NumIPAModes
+};
+
+/// AnalysisInlineFunctionSelection - Set of inlining function selection heuristics.
+enum AnalysisInliningMode {
+#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) NAME,
+#include "clang/Frontend/Analyses.def"
+NumInliningModes
+};
+
class AnalyzerOptions {
public:
/// \brief Pair of checker name and enable/disable.
@@ -68,6 +82,7 @@
AnalysisConstraints AnalysisConstraintsOpt;
AnalysisDiagClients AnalysisDiagOpt;
AnalysisPurgeMode AnalysisPurgeOpt;
+ AnalysisIPAMode IPAMode;
std::string AnalyzeSpecificFunction;
unsigned MaxNodes;
unsigned MaxLoop;
@@ -79,7 +94,6 @@
unsigned TrimGraph : 1;
unsigned VisualizeEGDot : 1;
unsigned VisualizeEGUbi : 1;
- unsigned InlineCall : 1;
unsigned UnoptimizedCFG : 1;
unsigned CFGAddImplicitDtors : 1;
unsigned CFGAddInitializers : 1;
@@ -87,6 +101,7 @@
unsigned PrintStats : 1;
unsigned InlineMaxStackDepth;
unsigned InlineMaxFunctionSize;
+ AnalysisInliningMode InliningMode;
public:
AnalyzerOptions() {
@@ -94,6 +109,7 @@
AnalysisConstraintsOpt = RangeConstraintsModel;
AnalysisDiagOpt = PD_HTML;
AnalysisPurgeOpt = PurgeStmt;
+ IPAMode = Inlining;
ShowCheckerHelp = 0;
AnalyzeAll = 0;
AnalyzerDisplayProgress = 0;
@@ -102,7 +118,6 @@
TrimGraph = 0;
VisualizeEGDot = 0;
VisualizeEGUbi = 0;
- InlineCall = 1;
UnoptimizedCFG = 0;
CFGAddImplicitDtors = 0;
CFGAddInitializers = 0;
@@ -111,6 +126,7 @@
// Cap the stack depth at 4 calls (5 stack frames, base + 4 calls).
InlineMaxStackDepth = 5;
InlineMaxFunctionSize = 200;
+ InliningMode = NoRedundancy;
}
};
Modified: cfe/branches/tooling/include/clang/Frontend/CodeGenOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Frontend/CodeGenOptions.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Frontend/CodeGenOptions.h (original)
+++ cfe/branches/tooling/include/clang/Frontend/CodeGenOptions.h Mon Mar 19 14:02:20 2012
@@ -78,6 +78,8 @@
unsigned NoGlobalMerge : 1; /// Set when -mno-global-merge is enabled.
unsigned NoImplicitFloat : 1; /// Set when -mno-implicit-float is enabled.
unsigned NoInfsFPMath : 1; /// Assume FP arguments, results not +-Inf.
+ unsigned NoInline : 1; /// Set when -fno-inline is enabled. Disables
+ /// use of the inline keyword.
unsigned NoNaNsFPMath : 1; /// Assume FP arguments, results not NaN.
unsigned NoZeroInitializedInBSS : 1; /// -fno-zero-initialized-in-bss
unsigned ObjCDispatchMethod : 2; /// Method of Objective-C dispatch to use.
@@ -187,6 +189,7 @@
NoDwarf2CFIAsm = 0;
NoImplicitFloat = 0;
NoInfsFPMath = 0;
+ NoInline = 0;
NoNaNsFPMath = 0;
NoZeroInitializedInBSS = 0;
NumRegisterParameters = 0;
Modified: cfe/branches/tooling/include/clang/Frontend/CompilerInvocation.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Frontend/CompilerInvocation.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Frontend/CompilerInvocation.h (original)
+++ cfe/branches/tooling/include/clang/Frontend/CompilerInvocation.h Mon Mar 19 14:02:20 2012
@@ -33,6 +33,17 @@
class CompilerInvocation;
class DiagnosticsEngine;
+
+namespace driver {
+class ArgList;
+}
+
+/// CompilerInvocation - Fill out Opts based on the options given in Args.
+/// Args must have been created from the OptTable returned by
+/// createCC1OptTable(). When errors are encountered, return false and,
+/// if Diags is non-null, report the error(s).
+bool ParseDiagnosticArgs(DiagnosticOptions &Opts, driver::ArgList &Args,
+ DiagnosticsEngine *Diags = 0);
class CompilerInvocationBase : public RefCountedBase<CompilerInvocation> {
protected:
Modified: cfe/branches/tooling/include/clang/Index/ASTLocation.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Index/ASTLocation.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Index/ASTLocation.h (original)
+++ cfe/branches/tooling/include/clang/Index/ASTLocation.h Mon Mar 19 14:02:20 2012
@@ -16,6 +16,7 @@
#include "clang/AST/TypeLoc.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Compiler.h"
namespace clang {
class Decl;
@@ -146,7 +147,7 @@
return const_cast<ASTLocation*>(this)->getReferencedDecl();
}
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
void print(raw_ostream &OS) const;
};
Modified: cfe/branches/tooling/include/clang/Lex/Lexer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Lex/Lexer.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Lex/Lexer.h (original)
+++ cfe/branches/tooling/include/clang/Lex/Lexer.h Mon Mar 19 14:02:20 2012
@@ -51,7 +51,7 @@
const char *BufferStart; // Start of the buffer.
const char *BufferEnd; // End of the buffer.
SourceLocation FileLoc; // Location for start of file.
- LangOptions Features; // Features enabled by this language (cache).
+ LangOptions LangOpts; // LangOpts enabled by this language (cache).
bool Is_PragmaLexer; // True if lexer for _Pragma handling.
//===--------------------------------------------------------------------===//
@@ -99,14 +99,14 @@
/// Lexer constructor - Create a new raw lexer object. This object is only
/// suitable for calls to 'LexRawToken'. This lexer assumes that the text
/// range will outlive it, so it doesn't take ownership of it.
- Lexer(SourceLocation FileLoc, const LangOptions &Features,
+ Lexer(SourceLocation FileLoc, const LangOptions &LangOpts,
const char *BufStart, const char *BufPtr, const char *BufEnd);
/// Lexer constructor - Create a new raw lexer object. This object is only
/// suitable for calls to 'LexRawToken'. This lexer assumes that the text
/// range will outlive it, so it doesn't take ownership of it.
Lexer(FileID FID, const llvm::MemoryBuffer *InputBuffer,
- const SourceManager &SM, const LangOptions &Features);
+ const SourceManager &SM, const LangOptions &LangOpts);
/// Create_PragmaLexer: Lexer constructor - Create a new lexer object for
/// _Pragma expansion. This has a variety of magic semantics that this method
@@ -117,9 +117,9 @@
unsigned TokLen, Preprocessor &PP);
- /// getFeatures - Return the language features currently enabled. NOTE: this
- /// lexer modifies features as a file is parsed!
- const LangOptions &getFeatures() const { return Features; }
+ /// getLangOpts - Return the language features currently enabled.
+ /// NOTE: this lexer modifies features as a file is parsed!
+ const LangOptions &getLangOpts() const { return LangOpts; }
/// getFileLoc - Return the File Location for the file we are lexing out of.
/// The physical location encodes the location where the characters come from,
@@ -240,7 +240,7 @@
/// if an internal buffer is returned.
static unsigned getSpelling(const Token &Tok, const char *&Buffer,
const SourceManager &SourceMgr,
- const LangOptions &Features,
+ const LangOptions &LangOpts,
bool *Invalid = 0);
/// getSpelling() - Return the 'spelling' of the Tok token. The spelling of a
@@ -250,7 +250,7 @@
/// UCNs, etc.
static std::string getSpelling(const Token &Tok,
const SourceManager &SourceMgr,
- const LangOptions &Features,
+ const LangOptions &LangOpts,
bool *Invalid = 0);
/// getSpelling - This method is used to get the spelling of the
@@ -264,7 +264,7 @@
static StringRef getSpelling(SourceLocation loc,
SmallVectorImpl<char> &buffer,
const SourceManager &SourceMgr,
- const LangOptions &Features,
+ const LangOptions &LangOpts,
bool *invalid = 0);
/// MeasureTokenLength - Relex the token at the specified location and return
@@ -290,7 +290,7 @@
static SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart,
unsigned Character,
const SourceManager &SM,
- const LangOptions &Features);
+ const LangOptions &LangOpts);
/// \brief Computes the source location just past the end of the
/// token at this source location.
@@ -309,7 +309,7 @@
/// a source location pointing to the last character in the token, etc.
static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset,
const SourceManager &SM,
- const LangOptions &Features);
+ const LangOptions &LangOpts);
/// \brief Returns true if the given MacroID location points at the first
/// token of the macro expansion.
@@ -372,7 +372,7 @@
/// of the file begins along with a boolean value indicating whether
/// the preamble ends at the beginning of a new line.
static std::pair<unsigned, bool>
- ComputePreamble(const llvm::MemoryBuffer *Buffer, const LangOptions &Features,
+ ComputePreamble(const llvm::MemoryBuffer *Buffer, const LangOptions &LangOpts,
unsigned MaxLines = 0);
//===--------------------------------------------------------------------===//
@@ -486,7 +486,7 @@
/// getCharAndSizeNoWarn - Like the getCharAndSize method, but does not ever
/// emit a warning.
static inline char getCharAndSizeNoWarn(const char *Ptr, unsigned &Size,
- const LangOptions &Features) {
+ const LangOptions &LangOpts) {
// If this is not a trigraph and not a UCN or escaped newline, return
// quickly.
if (isObviouslySimpleCharacter(Ptr[0])) {
@@ -495,7 +495,7 @@
}
Size = 0;
- return getCharAndSizeSlowNoWarn(Ptr, Size, Features);
+ return getCharAndSizeSlowNoWarn(Ptr, Size, LangOpts);
}
/// getEscapedNewLineSize - Return the size of the specified escaped newline,
@@ -524,7 +524,7 @@
/// getCharAndSizeSlowNoWarn - Same as getCharAndSizeSlow, but never emits a
/// diagnostic.
static char getCharAndSizeSlowNoWarn(const char *Ptr, unsigned &Size,
- const LangOptions &Features);
+ const LangOptions &LangOpts);
//===--------------------------------------------------------------------===//
// Other lexer functions.
Modified: cfe/branches/tooling/include/clang/Lex/PreprocessingRecord.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Lex/PreprocessingRecord.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Lex/PreprocessingRecord.h (original)
+++ cfe/branches/tooling/include/clang/Lex/PreprocessingRecord.h Mon Mar 19 14:02:20 2012
@@ -21,6 +21,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Compiler.h"
#include <vector>
namespace clang {
@@ -87,7 +88,7 @@
/// \brief Retrieve the source range that covers this entire preprocessed
/// entity.
- SourceRange getSourceRange() const { return Range; }
+ SourceRange getSourceRange() const LLVM_READONLY { return Range; }
/// \brief Returns true if there was a problem loading the preprocessed
/// entity.
Modified: cfe/branches/tooling/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Lex/Preprocessor.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Lex/Preprocessor.h (original)
+++ cfe/branches/tooling/include/clang/Lex/Preprocessor.h Mon Mar 19 14:02:20 2012
@@ -62,7 +62,7 @@
///
class Preprocessor : public RefCountedBase<Preprocessor> {
DiagnosticsEngine *Diags;
- LangOptions &Features;
+ LangOptions &LangOpts;
const TargetInfo *Target;
FileManager &FileMgr;
SourceManager &SourceMgr;
@@ -148,6 +148,10 @@
/// with this preprocessor.
std::vector<CommentHandler *> CommentHandlers;
+ /// \brief True if we want to ignore EOF token and continue later on (thus
+ /// avoid tearing the Lexer and etc. down).
+ bool IncrementalProcessing;
+
/// \brief The code-completion handler.
CodeCompletionHandler *CodeComplete;
@@ -344,7 +348,8 @@
ModuleLoader &TheModuleLoader,
IdentifierInfoLookup *IILookup = 0,
bool OwnsHeaderSearch = false,
- bool DelayInitialization = false);
+ bool DelayInitialization = false,
+ bool IncrProcessing = false);
~Preprocessor();
@@ -357,7 +362,7 @@
DiagnosticsEngine &getDiagnostics() const { return *Diags; }
void setDiagnostics(DiagnosticsEngine &D) { Diags = &D; }
- const LangOptions &getLangOptions() const { return Features; }
+ const LangOptions &getLangOpts() const { return LangOpts; }
const TargetInfo &getTargetInfo() const { return *Target; }
FileManager &getFileManager() const { return FileMgr; }
SourceManager &getSourceManager() const { return SourceMgr; }
@@ -691,6 +696,14 @@
/// \brief Recompute the current lexer kind based on the CurLexer/CurPTHLexer/
/// CurTokenLexer pointers.
void recomputeCurLexerKind();
+
+ /// \brief Returns true if incremental processing is enabled
+ bool isIncrementalProcessingEnabled() const { return IncrementalProcessing; }
+
+ /// \brief Enables the incremental processing
+ void enableIncrementalProcessing(bool value = true) {
+ IncrementalProcessing = value;
+ }
/// \brief Specify the point at which code-completion will be performed.
///
@@ -782,7 +795,7 @@
StringRef getSpelling(SourceLocation loc,
SmallVectorImpl<char> &buffer,
bool *invalid = 0) const {
- return Lexer::getSpelling(loc, buffer, SourceMgr, Features, invalid);
+ return Lexer::getSpelling(loc, buffer, SourceMgr, LangOpts, invalid);
}
/// getSpelling() - Return the 'spelling' of the Tok token. The spelling of a
@@ -793,7 +806,7 @@
///
/// \param Invalid If non-null, will be set \c true if an error occurs.
std::string getSpelling(const Token &Tok, bool *Invalid = 0) const {
- return Lexer::getSpelling(Tok, SourceMgr, Features, Invalid);
+ return Lexer::getSpelling(Tok, SourceMgr, LangOpts, Invalid);
}
/// getSpelling - This method is used to get the spelling of a token into a
@@ -808,7 +821,7 @@
/// if an internal buffer is returned.
unsigned getSpelling(const Token &Tok, const char *&Buffer,
bool *Invalid = 0) const {
- return Lexer::getSpelling(Tok, Buffer, SourceMgr, Features, Invalid);
+ return Lexer::getSpelling(Tok, Buffer, SourceMgr, LangOpts, Invalid);
}
/// getSpelling - This method is used to get the spelling of a token into a
@@ -843,7 +856,7 @@
/// refers to the SourceManager-owned buffer of the source where that macro
/// name is spelled. Thus, the result shouldn't out-live the SourceManager.
StringRef getImmediateMacroName(SourceLocation Loc) {
- return Lexer::getImmediateMacroName(Loc, SourceMgr, getLangOptions());
+ return Lexer::getImmediateMacroName(Loc, SourceMgr, getLangOpts());
}
/// CreateString - Plop the specified string into a scratch buffer and set the
@@ -869,7 +882,7 @@
/// location pointing just past the end of the token; an offset of 1 produces
/// a source location pointing to the last character in the token, etc.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0) {
- return Lexer::getLocForEndOfToken(Loc, Offset, SourceMgr, Features);
+ return Lexer::getLocForEndOfToken(Loc, Offset, SourceMgr, LangOpts);
}
/// \brief Returns true if the given MacroID location points at the first
@@ -879,7 +892,7 @@
/// begin location of the macro.
bool isAtStartOfMacroExpansion(SourceLocation loc,
SourceLocation *MacroBegin = 0) const {
- return Lexer::isAtStartOfMacroExpansion(loc, SourceMgr, Features,
+ return Lexer::isAtStartOfMacroExpansion(loc, SourceMgr, LangOpts,
MacroBegin);
}
@@ -890,7 +903,7 @@
/// end location of the macro.
bool isAtEndOfMacroExpansion(SourceLocation loc,
SourceLocation *MacroEnd = 0) const {
- return Lexer::isAtEndOfMacroExpansion(loc, SourceMgr, Features, MacroEnd);
+ return Lexer::isAtEndOfMacroExpansion(loc, SourceMgr, LangOpts, MacroEnd);
}
/// DumpToken - Print the token to stderr, used for debugging.
@@ -903,7 +916,7 @@
/// token, return a new location that specifies a character within the token.
SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart,
unsigned Char) const {
- return Lexer::AdvanceToTokenCharacter(TokStart, Char, SourceMgr, Features);
+ return Lexer::AdvanceToTokenCharacter(TokStart, Char, SourceMgr, LangOpts);
}
/// IncrementPasteCounter - Increment the counters for the number of token
@@ -1237,6 +1250,7 @@
void HandleIncludeNextDirective(SourceLocation HashLoc, Token &Tok);
void HandleIncludeMacrosDirective(SourceLocation HashLoc, Token &Tok);
void HandleImportDirective(SourceLocation HashLoc, Token &Tok);
+ void HandleMicrosoftImportDirective(Token &Tok);
// Macro handling.
void HandleDefineDirective(Token &Tok);
Modified: cfe/branches/tooling/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Parse/Parser.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Parse/Parser.h (original)
+++ cfe/branches/tooling/include/clang/Parse/Parser.h Mon Mar 19 14:02:20 2012
@@ -20,9 +20,10 @@
#include "clang/Lex/CodeCompletionHandler.h"
#include "clang/Sema/Sema.h"
#include "clang/Sema/DeclSpec.h"
-#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/PrettyStackTrace.h"
#include <stack>
namespace clang {
@@ -201,7 +202,7 @@
Parser(Preprocessor &PP, Sema &Actions);
~Parser();
- const LangOptions &getLang() const { return PP.getLangOptions(); }
+ const LangOptions &getLangOpts() const { return PP.getLangOpts(); }
const TargetInfo &getTargetInfo() const { return PP.getTargetInfo(); }
Preprocessor &getPreprocessor() const { return PP; }
Sema &getActions() const { return Actions; }
@@ -543,7 +544,7 @@
bool TryAltiVecToken(DeclSpec &DS, SourceLocation Loc,
const char *&PrevSpec, unsigned &DiagID,
bool &isInvalid) {
- if (!getLang().AltiVec ||
+ if (!getLangOpts().AltiVec ||
(Tok.getIdentifierInfo() != Ident_vector &&
Tok.getIdentifierInfo() != Ident_pixel))
return false;
@@ -555,7 +556,7 @@
/// identifier token, replacing it with the non-context-sensitive __vector.
/// This returns true if the token was replaced.
bool TryAltiVecVectorToken() {
- if (!getLang().AltiVec ||
+ if (!getLangOpts().AltiVec ||
Tok.getIdentifierInfo() != Ident_vector) return false;
return TryAltiVecVectorTokenOutOfLine();
}
@@ -1115,7 +1116,7 @@
/// \brief Whether the last template parameter list was empty.
bool LastParameterListWasEmpty;
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
};
/// \brief Contains a late templated function.
@@ -1620,6 +1621,8 @@
enum DeclSpecContext {
DSC_normal, // normal context
DSC_class, // class context, enables 'friend'
+ DSC_type_specifier, // C++ type-specifier-seq
+ DSC_trailing, // C++11 trailing-type-specifier in a trailing return type
DSC_top_level // top-level/namespace declaration context
};
@@ -1662,27 +1665,23 @@
bool ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
const ParsedTemplateInfo &TemplateInfo,
- AccessSpecifier AS);
+ AccessSpecifier AS, DeclSpecContext DSC);
DeclSpecContext getDeclSpecContextFromDeclaratorContext(unsigned Context);
void ParseDeclarationSpecifiers(DeclSpec &DS,
const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
AccessSpecifier AS = AS_none,
DeclSpecContext DSC = DSC_normal,
LateParsedAttrList *LateAttrs = 0);
- bool ParseOptionalTypeSpecifier(DeclSpec &DS, bool &isInvalid,
- const char *&PrevSpec,
- unsigned &DiagID,
- const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
- bool SuppressDeclarations = false);
- void ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS = AS_none);
+ void ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS = AS_none,
+ DeclSpecContext DSC = DSC_normal);
void ParseObjCTypeQualifierList(ObjCDeclSpec &DS,
Declarator::TheContext Context);
void ParseEnumSpecifier(SourceLocation TagLoc, DeclSpec &DS,
- const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
- AccessSpecifier AS = AS_none);
+ const ParsedTemplateInfo &TemplateInfo,
+ AccessSpecifier AS, DeclSpecContext DSC);
void ParseEnumBody(SourceLocation StartLoc, Decl *TagDecl);
void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
Decl *TagDecl);
@@ -1711,7 +1710,7 @@
/// expression statement, when parsing function bodies.
/// Returns true for declaration, false for expression.
bool isDeclarationStatement() {
- if (getLang().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
return isCXXDeclarationStatement();
return isDeclarationSpecifier(true);
}
@@ -1721,7 +1720,7 @@
// 'for-init-statement' part of a 'for' statement.
/// Returns true for declaration, false for expression.
bool isForInitDeclaration() {
- if (getLang().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
return isCXXSimpleDeclaration(/*AllowForRangeDecl=*/true);
return isDeclarationSpecifier(true);
}
@@ -1747,7 +1746,7 @@
/// whether the parens contain an expression or a type-id.
/// Returns true for a type-id and false for an expression.
bool isTypeIdInParens(bool &isAmbiguous) {
- if (getLang().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
return isCXXTypeId(TypeIdInParens, isAmbiguous);
isAmbiguous = false;
return isTypeSpecifierQualifier();
@@ -1889,7 +1888,7 @@
SourceLocation *EndLoc);
void MaybeParseCXX0XAttributes(Declarator &D) {
- if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
+ if (getLangOpts().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
ParsedAttributesWithRange attrs(AttrFactory);
SourceLocation endLoc;
ParseCXX0XAttributes(attrs, &endLoc);
@@ -1898,7 +1897,7 @@
}
void MaybeParseCXX0XAttributes(ParsedAttributes &attrs,
SourceLocation *endLoc = 0) {
- if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
+ if (getLangOpts().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
ParsedAttributesWithRange attrsWithRange(AttrFactory);
ParseCXX0XAttributes(attrsWithRange, endLoc);
attrs.takeAllFrom(attrsWithRange);
@@ -1906,7 +1905,7 @@
}
void MaybeParseCXX0XAttributes(ParsedAttributesWithRange &attrs,
SourceLocation *endLoc = 0) {
- if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
+ if (getLangOpts().CPlusPlus0x && isCXX0XAttributeSpecifier())
ParseCXX0XAttributes(attrs, endLoc);
}
@@ -1917,7 +1916,7 @@
void MaybeParseMicrosoftAttributes(ParsedAttributes &attrs,
SourceLocation *endLoc = 0) {
- if (getLang().MicrosoftExt && Tok.is(tok::l_square))
+ if (getLangOpts().MicrosoftExt && Tok.is(tok::l_square))
ParseMicrosoftAttributes(attrs, endLoc);
}
void ParseMicrosoftAttributes(ParsedAttributes &attrs,
@@ -2059,11 +2058,9 @@
//===--------------------------------------------------------------------===//
// C++ 9: classes [class] and C structs/unions.
void ParseClassSpecifier(tok::TokenKind TagTokKind, SourceLocation TagLoc,
- DeclSpec &DS,
- const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
- AccessSpecifier AS = AS_none,
- bool EnteringContext = false,
- bool SuppressDeclarations = false);
+ DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo,
+ AccessSpecifier AS, bool EnteringContext,
+ DeclSpecContext DSC);
void ParseCXXMemberSpecification(SourceLocation StartLoc, unsigned TagType,
Decl *TagDecl);
ExprResult ParseCXXMemberInitializer(Decl *D, bool IsFunction,
Modified: cfe/branches/tooling/include/clang/Sema/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Sema/DeclSpec.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/DeclSpec.h (original)
+++ cfe/branches/tooling/include/clang/Sema/DeclSpec.h Mon Mar 19 14:02:20 2012
@@ -29,6 +29,7 @@
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
namespace clang {
@@ -446,7 +447,10 @@
CXXScopeSpec &getTypeSpecScope() { return TypeScope; }
const CXXScopeSpec &getTypeSpecScope() const { return TypeScope; }
- const SourceRange &getSourceRange() const { return Range; }
+ const SourceRange &getSourceRange() const LLVM_READONLY { return Range; }
+ SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
+
SourceLocation getTypeSpecWidthLoc() const { return TSWLoc; }
SourceLocation getTypeSpecComplexLoc() const { return TSCLoc; }
SourceLocation getTypeSpecSignLoc() const { return TSSLoc; }
@@ -610,6 +614,11 @@
bool isConstexprSpecified() const { return Constexpr_specified; }
SourceLocation getConstexprSpecLoc() const { return ConstexprLoc; }
+ void ClearConstexprSpec() {
+ Constexpr_specified = false;
+ ConstexprLoc = SourceLocation();
+ }
+
AttributePool &getAttributePool() const {
return Attrs.getPool();
}
@@ -963,9 +972,11 @@
void setTemplateId(TemplateIdAnnotation *TemplateId);
/// \brief Return the source range that covers this unqualified-id.
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(StartLocation, EndLocation);
}
+ SourceLocation getLocStart() const LLVM_READONLY { return StartLocation; }
+ SourceLocation getLocEnd() const LLVM_READONLY { return EndLocation; }
};
/// CachedTokens - A set of tokens that has been cached for later
@@ -1417,9 +1428,10 @@
ObjCCatchContext, // Objective-C catch exception-declaration
BlockLiteralContext, // Block literal declarator.
LambdaExprContext, // Lambda-expression declarator.
+ TrailingReturnContext, // C++11 trailing-type-specifier.
TemplateTypeArgContext, // Template type argument.
- AliasDeclContext, // C++0x alias-declaration.
- AliasTemplateContext // C++0x alias-declaration template.
+ AliasDeclContext, // C++11 alias-declaration.
+ AliasTemplateContext // C++11 alias-declaration template.
};
private:
@@ -1524,7 +1536,9 @@
}
/// getSourceRange - Get the source range that spans this declarator.
- const SourceRange &getSourceRange() const { return Range; }
+ const SourceRange &getSourceRange() const LLVM_READONLY { return Range; }
+ SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
void SetSourceRange(SourceRange R) { Range = R; }
/// SetRangeBegin - Set the start of the source range to Loc, unless it's
@@ -1591,6 +1605,7 @@
case BlockLiteralContext:
case LambdaExprContext:
case TemplateTypeArgContext:
+ case TrailingReturnContext:
return true;
}
llvm_unreachable("unknown context kind!");
@@ -1622,6 +1637,7 @@
case BlockLiteralContext:
case LambdaExprContext:
case TemplateTypeArgContext:
+ case TrailingReturnContext:
return false;
}
llvm_unreachable("unknown context kind!");
@@ -1666,6 +1682,7 @@
case BlockLiteralContext:
case LambdaExprContext:
case TemplateTypeArgContext:
+ case TrailingReturnContext:
return false;
}
llvm_unreachable("unknown context kind!");
Modified: cfe/branches/tooling/include/clang/Sema/Initialization.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Sema/Initialization.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/Initialization.h (original)
+++ cfe/branches/tooling/include/clang/Sema/Initialization.h Mon Mar 19 14:02:20 2012
@@ -175,7 +175,7 @@
/// \brief Create the initialization entity for a parameter.
static InitializedEntity InitializeParameter(ASTContext &Context,
ParmVarDecl *Parm) {
- bool Consumed = (Context.getLangOptions().ObjCAutoRefCount &&
+ bool Consumed = (Context.getLangOpts().ObjCAutoRefCount &&
Parm->hasAttr<NSConsumedAttr>());
InitializedEntity Entity;
Modified: cfe/branches/tooling/include/clang/Sema/Lookup.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Sema/Lookup.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/Lookup.h (original)
+++ cfe/branches/tooling/include/clang/Sema/Lookup.h Mon Mar 19 14:02:20 2012
@@ -550,6 +550,11 @@
return *I++;
}
+ /// Restart the iteration.
+ void restart() {
+ I = Results.begin();
+ }
+
/// Erase the last element returned from this iterator.
void erase() {
Results.Decls.erase(--I);
@@ -587,7 +592,7 @@
void diagnose() {
if (isAmbiguous())
SemaRef.DiagnoseAmbiguousLookup(*this);
- else if (isClassLookup() && SemaRef.getLangOptions().AccessControl)
+ else if (isClassLookup() && SemaRef.getLangOpts().AccessControl)
SemaRef.CheckLookupAccess(*this);
}
Modified: cfe/branches/tooling/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Sema/Sema.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/Sema.h (original)
+++ cfe/branches/tooling/include/clang/Sema/Sema.h Mon Mar 19 14:02:20 2012
@@ -735,6 +735,12 @@
/// Private Helper predicate to check for 'self'.
bool isSelfExpr(Expr *RExpr);
+
+ /// \brief Cause the active diagnostic on the DiagosticsEngine to be
+ /// emitted. This is closely coupled to the SemaDiagnosticBuilder class and
+ /// should not be used elsewhere.
+ void EmitCurrentDiagnostic(unsigned DiagID);
+
public:
Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
TranslationUnitKind TUKind = TU_Complete,
@@ -745,7 +751,7 @@
/// initialized but before it parses anything.
void Initialize();
- const LangOptions &getLangOptions() const { return LangOpts; }
+ const LangOptions &getLangOpts() const { return LangOpts; }
OpenCLOptions &getOpenCLOptions() { return OpenCLFeatures; }
FPOptions &getFPOptions() { return FPFeatures; }
@@ -776,14 +782,32 @@
SemaDiagnosticBuilder(DiagnosticBuilder &DB, Sema &SemaRef, unsigned DiagID)
: DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) { }
- explicit SemaDiagnosticBuilder(Sema &SemaRef)
- : DiagnosticBuilder(DiagnosticBuilder::Suppress), SemaRef(SemaRef) { }
+ ~SemaDiagnosticBuilder() {
+ // If we aren't active, there is nothing to do.
+ if (!isActive()) return;
+
+ // Otherwise, we need to emit the diagnostic. First flush the underlying
+ // DiagnosticBuilder data, and clear the diagnostic builder itself so it
+ // won't emit the diagnostic in its own destructor.
+ //
+ // This seems wasteful, in that as written the DiagnosticBuilder dtor will
+ // do its own needless checks to see if the diagnostic needs to be
+ // emitted. However, because we take care to ensure that the builder
+ // objects never escape, a sufficiently smart compiler will be able to
+ // eliminate that code.
+ FlushCounts();
+ Clear();
- ~SemaDiagnosticBuilder();
+ // Dispatch to Sema to emit the diagnostic.
+ SemaRef.EmitCurrentDiagnostic(DiagID);
+ }
};
/// \brief Emit a diagnostic.
- SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
+ SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
+ DiagnosticBuilder DB = Diags.Report(Loc, DiagID);
+ return SemaDiagnosticBuilder(DB, *this, DiagID);
+ }
/// \brief Emit a partial diagnostic.
SemaDiagnosticBuilder Diag(SourceLocation Loc, const PartialDiagnostic& PD);
@@ -1067,6 +1091,9 @@
const LookupResult &Previous,
Scope *S);
bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info);
+ bool diagnoseQualifiedDeclInClass(CXXScopeSpec &SS, DeclContext *DC,
+ DeclarationName Name,
+ SourceLocation Loc);
void DiagnoseFunctionSpecifiers(Declarator& D);
void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R);
void CheckShadow(Scope *S, VarDecl *D);
@@ -1319,6 +1346,9 @@
SourceLocation IdLoc,
IdentifierInfo *Id,
Expr *val);
+ bool CheckEnumUnderlyingType(TypeSourceInfo *TI);
+ bool CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped,
+ QualType EnumUnderlyingTy, const EnumDecl *Prev);
Decl *ActOnEnumConstant(Scope *S, Decl *EnumDecl, Decl *LastEnumConstant,
SourceLocation IdLoc, IdentifierInfo *Id,
@@ -1392,13 +1422,14 @@
bool isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New);
void mergeDeclAttributes(Decl *New, Decl *Old, bool MergeDeprecation = true);
void MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls);
- bool MergeFunctionDecl(FunctionDecl *New, Decl *Old);
- bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old);
+ bool MergeFunctionDecl(FunctionDecl *New, Decl *Old, Scope *S);
+ bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old,
+ Scope *S);
void mergeObjCMethodDecls(ObjCMethodDecl *New, ObjCMethodDecl *Old);
void MergeVarDecl(VarDecl *New, LookupResult &OldDecls);
void MergeVarDeclTypes(VarDecl *New, VarDecl *Old);
void MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old);
- bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old);
+ bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Scope *S);
// AssignmentAction - This is used by all the assignment diagnostic functions
// to represent what is actually causing the operation
@@ -1552,7 +1583,8 @@
void AddFunctionCandidates(const UnresolvedSetImpl &Functions,
llvm::ArrayRef<Expr *> Args,
OverloadCandidateSet& CandidateSet,
- bool SuppressUserConversions = false);
+ bool SuppressUserConversions = false,
+ TemplateArgumentListInfo *ExplicitTemplateArgs = 0);
void AddMethodCandidate(DeclAccessPair FoundDecl,
QualType ObjectType,
Expr::Classification ObjectClassification,
@@ -1794,6 +1826,22 @@
ForRedeclaration
};
+ /// \brief The possible outcomes of name lookup for a literal operator.
+ enum LiteralOperatorLookupResult {
+ /// \brief The lookup resulted in an error.
+ LOLR_Error,
+ /// \brief The lookup found a single 'cooked' literal operator, which
+ /// expects a normal literal to be built and passed to it.
+ LOLR_Cooked,
+ /// \brief The lookup found a single 'raw' literal operator, which expects
+ /// a string literal containing the spelling of the literal token.
+ LOLR_Raw,
+ /// \brief The lookup found an overload set of literal operator templates,
+ /// which expect the characters of the spelling of the literal token to be
+ /// passed as a non-type template argument pack.
+ LOLR_Template
+ };
+
SpecialMemberOverloadResult *LookupSpecialMember(CXXRecordDecl *D,
CXXSpecialMember SM,
bool ConstArg,
@@ -1857,6 +1905,10 @@
unsigned ThisQuals);
CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class);
+ LiteralOperatorLookupResult LookupLiteralOperator(Scope *S, LookupResult &R,
+ ArrayRef<QualType> ArgTys,
+ bool AllowRawAndTemplate);
+
void ArgumentDependentLookup(DeclarationName Name, bool Operator,
SourceLocation Loc,
llvm::ArrayRef<Expr *> Args,
@@ -2398,7 +2450,6 @@
void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D);
void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func);
void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var);
- void MarkBlockDeclRefReferenced(BlockDeclRefExpr *E);
void MarkDeclRefReferenced(DeclRefExpr *E);
void MarkMemberReferenced(MemberExpr *E);
@@ -2545,15 +2596,16 @@
const DeclarationNameInfo &NameInfo,
NamedDecl *D);
- ExprResult BuildLiteralOperatorCall(IdentifierInfo *UDSuffix,
- SourceLocation UDSuffixLoc,
+ ExprResult BuildLiteralOperatorCall(LookupResult &R,
+ DeclarationNameInfo &SuffixInfo,
ArrayRef<Expr*> Args,
- SourceLocation LitEndLoc);
+ SourceLocation LitEndLoc,
+ TemplateArgumentListInfo *ExplicitTemplateArgs = 0);
ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind);
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val);
- ExprResult ActOnNumericConstant(const Token &Tok);
- ExprResult ActOnCharacterConstant(const Token &Tok);
+ ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = 0);
+ ExprResult ActOnCharacterConstant(const Token &Tok, Scope *UDLScope = 0);
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E);
ExprResult ActOnParenListExpr(SourceLocation L,
SourceLocation R,
@@ -2561,8 +2613,8 @@
/// ActOnStringLiteral - The specified tokens were lexed as pasted string
/// fragments (e.g. "foo" "bar" L"baz").
- ExprResult ActOnStringLiteral(const Token *StringToks,
- unsigned NumStringToks);
+ ExprResult ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks,
+ Scope *UDLScope = 0);
ExprResult ActOnGenericSelectionExpr(SourceLocation KeyLoc,
SourceLocation DefaultLoc,
@@ -3003,7 +3055,7 @@
public:
explicit ImplicitExceptionSpecification(ASTContext &Context)
: Context(&Context), ComputedEST(EST_BasicNoexcept) {
- if (!Context.getLangOptions().CPlusPlus0x)
+ if (!Context.getLangOpts().CPlusPlus0x)
ComputedEST = EST_DynamicNone;
}
@@ -4110,8 +4162,10 @@
//===--------------------------------------------------------------------===//
// C++ Templates [C++ 14]
//
- void FilterAcceptableTemplateNames(LookupResult &R);
- bool hasAnyAcceptableTemplateNames(LookupResult &R);
+ void FilterAcceptableTemplateNames(LookupResult &R,
+ bool AllowFunctionTemplates = true);
+ bool hasAnyAcceptableTemplateNames(LookupResult &R,
+ bool AllowFunctionTemplates = true);
void LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS,
QualType ObjectType, bool EnteringContext,
@@ -5441,6 +5495,11 @@
TemplateSpecializationKind TSK,
bool Complain = true);
+ bool InstantiateEnum(SourceLocation PointOfInstantiation,
+ EnumDecl *Instantiation, EnumDecl *Pattern,
+ const MultiLevelTemplateArgumentList &TemplateArgs,
+ TemplateSpecializationKind TSK);
+
struct LateInstantiatedAttribute {
const Attr *TmplAttr;
LocalInstantiationScope *Scope;
Modified: cfe/branches/tooling/include/clang/Sema/Template.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Sema/Template.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/Template.h (original)
+++ cfe/branches/tooling/include/clang/Sema/Template.h Mon Mar 19 14:02:20 2012
@@ -484,6 +484,7 @@
InstantiateClassTemplatePartialSpecialization(
ClassTemplateDecl *ClassTemplate,
ClassTemplatePartialSpecializationDecl *PartialSpec);
+ void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern);
};
}
Modified: cfe/branches/tooling/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Serialization/ASTBitCodes.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/branches/tooling/include/clang/Serialization/ASTBitCodes.h Mon Mar 19 14:02:20 2012
@@ -1052,8 +1052,6 @@
EXPR_SHUFFLE_VECTOR,
/// \brief BlockExpr
EXPR_BLOCK,
- /// \brief A BlockDeclRef record.
- EXPR_BLOCK_DECL_REF,
/// \brief A GenericSelectionExpr record.
EXPR_GENERIC_SELECTION,
/// \brief A PseudoObjectExpr record.
Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h Mon Mar 19 14:02:20 2012
@@ -23,6 +23,7 @@
#include "llvm/ADT/ImmutableList.h"
#include "llvm/ADT/ImmutableSet.h"
#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/DenseSet.h"
#include <list>
namespace clang {
@@ -50,7 +51,7 @@
/// This class provides an interface through which checkers can create
/// individual bug reports.
class BugReport {
-public:
+public:
class NodeResolver {
virtual void anchor();
public:
@@ -75,6 +76,19 @@
const ExplodedNode *ErrorNode;
SmallVector<SourceRange, 4> Ranges;
ExtraTextList ExtraText;
+
+ typedef llvm::DenseSet<SymbolRef> Symbols;
+ typedef llvm::DenseSet<const MemRegion *> Regions;
+
+ /// A set of symbols that are registered with this report as being
+ /// "interesting", and thus used to help decide which diagnostics
+ /// to include when constructing the final path diagnostic.
+ Symbols interestingSymbols;
+
+ /// A set of regions that are registered with this report as being
+ /// "interesting", and thus used to help decide which diagnostics
+ /// to include when constructing the final path diagnostic.
+ Regions interestingRegions;
// Not the most efficient data structure, but we use an ImmutableList for the
// Callbacks because it is safe to make additions to list during iteration.
@@ -121,6 +135,14 @@
return ShortDescription.empty() ? Description : ShortDescription;
}
+ void markInteresting(SymbolRef sym);
+ void markInteresting(const MemRegion *R);
+ void markInteresting(SVal V);
+
+ bool isInteresting(SymbolRef sym) const;
+ bool isInteresting(const MemRegion *R) const;
+ bool isInteresting(SVal V) const;
+
/// \brief This allows for addition of meta data to the diagnostic.
///
/// Currently, only the HTMLDiagnosticClient knows how to display it.
@@ -351,7 +373,6 @@
// FIXME: Get rid of GRBugReporter. It's the wrong abstraction.
class GRBugReporter : public BugReporter {
ExprEngine& Eng;
- llvm::SmallSet<SymbolRef, 10> NotableSymbols;
public:
GRBugReporter(BugReporterData& d, ExprEngine& eng)
: BugReporter(d, GRBugReporterKind), Eng(eng) {}
@@ -373,14 +394,6 @@
virtual void GeneratePathDiagnostic(PathDiagnostic &pathDiagnostic,
SmallVectorImpl<BugReport*> &bugReports);
- void addNotableSymbol(SymbolRef Sym) {
- NotableSymbols.insert(Sym);
- }
-
- bool isNotable(SymbolRef Sym) const {
- return (bool) NotableSymbols.count(Sym);
- }
-
/// classof - Used by isa<>, cast<>, and dyn_cast<>.
static bool classof(const BugReporter* R) {
return R->getKind() == GRBugReporterKind;
@@ -399,16 +412,6 @@
ExplodedGraph &getGraph() { return BR.getGraph(); }
- void addNotableSymbol(SymbolRef Sym) {
- // FIXME: For now forward to GRBugReporter.
- BR.addNotableSymbol(Sym);
- }
-
- bool isNotable(SymbolRef Sym) const {
- // FIXME: For now forward to GRBugReporter.
- return BR.isNotable(Sym);
- }
-
ProgramStateManager& getStateManager() {
return BR.getStateManager();
}
Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h Mon Mar 19 14:02:20 2012
@@ -147,40 +147,49 @@
const ExplodedNode *N,
const CFGBlock *srcBlk,
const CFGBlock *dstBlk,
+ BugReport &R,
BugReporterContext &BRC);
PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
bool tookTrue,
BugReporterContext &BRC,
- const LocationContext *LC);
+ BugReport &R,
+ const ExplodedNode *N);
PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
const DeclRefExpr *DR,
const bool tookTrue,
BugReporterContext &BRC,
- const LocationContext *LC);
+ BugReport &R,
+ const ExplodedNode *N);
PathDiagnosticPiece *VisitTrueTest(const Expr *Cond,
const BinaryOperator *BExpr,
const bool tookTrue,
BugReporterContext &BRC,
- const LocationContext *LC);
+ BugReport &R,
+ const ExplodedNode *N);
PathDiagnosticPiece *VisitConditionVariable(StringRef LhsString,
const Expr *CondVarExpr,
const bool tookTrue,
BugReporterContext &BRC,
- const LocationContext *LC);
+ BugReport &R,
+ const ExplodedNode *N);
bool patternMatch(const Expr *Ex,
llvm::raw_ostream &Out,
- BugReporterContext &BRC);
+ BugReporterContext &BRC,
+ BugReport &R,
+ const ExplodedNode *N,
+ llvm::Optional<bool> &prunable);
};
namespace bugreporter {
BugReporterVisitor *getTrackNullOrUndefValueVisitor(const ExplodedNode *N,
- const Stmt *S);
+ const Stmt *S,
+ BugReport *R);
const Stmt *GetDerefExpr(const ExplodedNode *N);
const Stmt *GetDenomExpr(const ExplodedNode *N);
Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h Mon Mar 19 14:02:20 2012
@@ -19,6 +19,7 @@
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/Optional.h"
#include <deque>
#include <iterator>
#include <string>
@@ -40,6 +41,8 @@
namespace ento {
class ExplodedNode;
+class SymExpr;
+typedef const SymExpr* SymbolRef;
//===----------------------------------------------------------------------===//
// High-level interface for handlers of path-sensitive diagnostics.
@@ -356,19 +359,96 @@
virtual void Profile(llvm::FoldingSetNodeID &ID) const;
};
+/// \brief Interface for classes constructing Stack hints.
+///
+/// If a PathDiagnosticEvent occurs in a different frame than the final
+/// diagnostic the hints can be used to summarise the effect of the call.
+class StackHintGenerator {
+public:
+ virtual ~StackHintGenerator() = 0;
+
+ /// \brief Construct the Diagnostic message for the given ExplodedNode.
+ virtual std::string getMessage(const ExplodedNode *N) = 0;
+};
+
+/// \brief Constructs a Stack hint for the given symbol.
+///
+/// The class knows how to construct the stack hint message based on
+/// traversing the CallExpr associated with the call and checking if the given
+/// symbol is returned or is one of the arguments.
+/// The hint can be customized by redefining 'getMessageForX()' methods.
+class StackHintGeneratorForSymbol : public StackHintGenerator {
+private:
+ SymbolRef Sym;
+ std::string Msg;
+
+public:
+ StackHintGeneratorForSymbol(SymbolRef S, StringRef M) : Sym(S), Msg(M) {}
+ virtual ~StackHintGeneratorForSymbol() {}
+
+ /// \brief Search the call expression for the symbol Sym and dispatch the
+ /// 'getMessageForX()' methods to construct a specific message.
+ virtual std::string getMessage(const ExplodedNode *N);
+
+ /// Prints the ordinal form of the given integer,
+ /// only valid for ValNo : ValNo > 0.
+ void printOrdinal(unsigned ValNo, llvm::raw_svector_ostream &Out);
+
+ /// Produces the message of the following form:
+ /// 'Msg via Nth parameter'
+ virtual std::string getMessageForArg(const Expr *ArgE, unsigned ArgIndex);
+ virtual std::string getMessageForReturn(const CallExpr *CallExpr) {
+ return Msg;
+ }
+ virtual std::string getMessageForSymbolNotFound() {
+ return Msg;
+ }
+};
+
class PathDiagnosticEventPiece : public PathDiagnosticSpotPiece {
- bool IsPrunable;
+ llvm::Optional<bool> IsPrunable;
+
+ /// If the event occurs in a different frame than the final diagnostic,
+ /// supply a message that will be used to construct an extra hint on the
+ /// returns from all the calls on the stack from this event to the final
+ /// diagnostic.
+ llvm::OwningPtr<StackHintGenerator> CallStackHint;
+
public:
PathDiagnosticEventPiece(const PathDiagnosticLocation &pos,
- StringRef s, bool addPosRange = true)
+ StringRef s, bool addPosRange = true,
+ StackHintGenerator *stackHint = 0)
: PathDiagnosticSpotPiece(pos, s, Event, addPosRange),
- IsPrunable(false) {}
+ CallStackHint(stackHint) {}
~PathDiagnosticEventPiece();
- void setPrunable(bool isPrunable) { IsPrunable = isPrunable; }
- bool isPrunable() const { return IsPrunable; }
-
+ /// Mark the diagnostic piece as being potentially prunable. This
+ /// flag may have been previously set, at which point it will not
+ /// be reset unless one specifies to do so.
+ void setPrunable(bool isPrunable, bool override = false) {
+ if (IsPrunable.hasValue() && !override)
+ return;
+ IsPrunable = isPrunable;
+ }
+
+ /// Return true if the diagnostic piece is prunable.
+ bool isPrunable() const {
+ return IsPrunable.hasValue() ? IsPrunable.getValue() : false;
+ }
+
+ bool hasCallStackHint() {
+ return (CallStackHint != 0);
+ }
+
+ /// Produce the hint for the given node. The node contains
+ /// information about the call for which the diagnostic can be generated.
+ std::string getCallStackMessage(const ExplodedNode *N) {
+ if (CallStackHint)
+ return CallStackHint->getMessage(N);
+ return "";
+ }
+
static inline bool classof(const PathDiagnosticPiece *P) {
return P->getKind() == Event;
}
@@ -377,14 +457,24 @@
class PathDiagnosticCallPiece : public PathDiagnosticPiece {
PathDiagnosticCallPiece(const Decl *callerD,
const PathDiagnosticLocation &callReturnPos)
- : PathDiagnosticPiece(Call), Caller(callerD),
- Callee(0), callReturn(callReturnPos) {}
+ : PathDiagnosticPiece(Call), Caller(callerD), Callee(0),
+ NoExit(false), callReturn(callReturnPos) {}
- PathDiagnosticCallPiece(PathPieces &oldPath)
- : PathDiagnosticPiece(Call), Caller(0), Callee(0), path(oldPath) {}
+ PathDiagnosticCallPiece(PathPieces &oldPath, const Decl *caller)
+ : PathDiagnosticPiece(Call), Caller(caller), Callee(0),
+ NoExit(true), path(oldPath) {}
const Decl *Caller;
const Decl *Callee;
+
+ // Flag signifying that this diagnostic has only call enter and no matching
+ // call exit.
+ bool NoExit;
+
+ // The custom string, which should appear after the call Return Diagnostic.
+ // TODO: Should we allow multiple diagnostics?
+ std::string CallStackMessage;
+
public:
PathDiagnosticLocation callEnter;
PathDiagnosticLocation callEnterWithin;
@@ -398,6 +488,11 @@
const Decl *getCallee() const { return Callee; }
void setCallee(const CallEnter &CE, const SourceManager &SM);
+ bool hasCallStackMessage() { return !CallStackMessage.empty(); }
+ void setCallStackMessage(StringRef st) {
+ CallStackMessage = st;
+ }
+
virtual PathDiagnosticLocation getLocation() const {
return callEnter;
}
@@ -418,7 +513,8 @@
const CallExit &CE,
const SourceManager &SM);
- static PathDiagnosticCallPiece *construct(PathPieces &pieces);
+ static PathDiagnosticCallPiece *construct(PathPieces &pieces,
+ const Decl *caller);
virtual void Profile(llvm::FoldingSetNodeID &ID) const;
Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/CheckerManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/CheckerManager.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/CheckerManager.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/CheckerManager.h Mon Mar 19 14:02:20 2012
@@ -128,7 +128,7 @@
void finishedCheckerRegistration();
- const LangOptions &getLangOptions() const { return LangOpts; }
+ const LangOptions &getLangOpts() const { return LangOpts; }
typedef CheckerBase *CheckerRef;
typedef const void *CheckerTag;
Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h Mon Mar 19 14:02:20 2012
@@ -32,6 +32,10 @@
PathDiagnosticConsumer *SubPD = 0);
PathDiagnosticConsumer*
+createPlistMultiFileDiagnosticConsumer(const std::string& prefix,
+ const Preprocessor &PP);
+
+PathDiagnosticConsumer*
createTextPathDiagnosticConsumer(const std::string& prefix,
const Preprocessor &PP);
Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h Mon Mar 19 14:02:20 2012
@@ -30,13 +30,15 @@
namespace ento {
class CheckerManager;
+typedef llvm::SmallPtrSet<const Decl*,24> SetOfDecls;
+
class AnalysisManager : public BugReporterData {
virtual void anchor();
AnalysisDeclContextManager AnaCtxMgr;
ASTContext &Ctx;
DiagnosticsEngine &Diags;
- const LangOptions &LangInfo;
+ const LangOptions &LangOpts;
OwningPtr<PathDiagnosticConsumer> PD;
@@ -75,16 +77,19 @@
/// bifurcates paths.
bool EagerlyAssume;
bool TrimGraph;
- bool InlineCall;
bool EagerlyTrimEGraph;
public:
- // Settings for inlining tuning.
+ // \brief inter-procedural analysis mode.
+ AnalysisIPAMode IPAMode;
+ // Settings for inlining tuning.
/// \brief The inlining stack depth limit.
unsigned InlineMaxStackDepth;
/// \brief The max number of basic blocks in a function being inlined.
unsigned InlineMaxFunctionSize;
+ /// \brief The mode of function selection used during inlining.
+ AnalysisInliningMode InliningMode;
public:
AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags,
@@ -96,11 +101,13 @@
unsigned maxnodes, unsigned maxvisit,
bool vizdot, bool vizubi, AnalysisPurgeMode purge,
bool eager, bool trim,
- bool inlinecall, bool useUnoptimizedCFG,
+ bool useUnoptimizedCFG,
bool addImplicitDtors, bool addInitializers,
bool eagerlyTrimEGraph,
+ AnalysisIPAMode ipa,
unsigned inlineMaxStack,
- unsigned inlineMaxFunctionSize);
+ unsigned inlineMaxFunctionSize,
+ AnalysisInliningMode inliningMode);
/// Construct a clone of the given AnalysisManager with the given ASTContext
/// and DiagnosticsEngine.
@@ -141,8 +148,8 @@
return Diags;
}
- const LangOptions &getLangOptions() const {
- return LangInfo;
+ const LangOptions &getLangOpts() const {
+ return LangOpts;
}
virtual PathDiagnosticConsumer *getPathDiagnosticConsumer() {
@@ -174,7 +181,7 @@
bool shouldEagerlyAssume() const { return EagerlyAssume; }
- bool shouldInlineCall() const { return InlineCall; }
+ bool shouldInlineCall() const { return (IPAMode == Inlining); }
bool hasIndexer() const { return Idxer != 0; }
Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h Mon Mar 19 14:02:20 2012
@@ -78,8 +78,8 @@
return Eng.getContext();
}
- const LangOptions &getLangOptions() const {
- return Eng.getContext().getLangOptions();
+ const LangOptions &getLangOpts() const {
+ return Eng.getContext().getLangOpts();
}
const LocationContext *getLocationContext() const {
Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h Mon Mar 19 14:02:20 2012
@@ -78,6 +78,10 @@
/// usually because it could not reason about something.
BlocksAborted blocksAborted;
+ /// The functions which have been analyzed through inlining. This is owned by
+ /// AnalysisConsumer. It can be null.
+ SetOfDecls *AnalyzedCallees;
+
void generateNode(const ProgramPoint &Loc,
ProgramStateRef State,
ExplodedNode *Pred);
@@ -102,17 +106,11 @@
public:
/// Construct a CoreEngine object to analyze the provided CFG using
/// a DFS exploration of the exploded graph.
- CoreEngine(SubEngine& subengine)
+ CoreEngine(SubEngine& subengine, SetOfDecls *VisitedCallees)
: SubEng(subengine), G(new ExplodedGraph()),
WList(WorkList::makeBFS()),
- BCounterFactory(G->getAllocator()) {}
-
- /// Construct a CoreEngine object to analyze the provided CFG and to
- /// use the provided worklist object to execute the worklist algorithm.
- /// The CoreEngine object assumes ownership of 'wlist'.
- CoreEngine(WorkList* wlist, SubEngine& subengine)
- : SubEng(subengine), G(new ExplodedGraph()), WList(wlist),
- BCounterFactory(G->getAllocator()) {}
+ BCounterFactory(G->getAllocator()),
+ AnalyzedCallees(VisitedCallees) {}
~CoreEngine() {
delete WList;
Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Mon Mar 19 14:02:20 2012
@@ -27,6 +27,7 @@
namespace clang {
class AnalysisDeclContextManager;
+class CXXCatchStmt;
class CXXConstructExpr;
class CXXDeleteExpr;
class CXXNewExpr;
@@ -89,7 +90,7 @@
GRBugReporter BR;
public:
- ExprEngine(AnalysisManager &mgr, bool gcEnabled);
+ ExprEngine(AnalysisManager &mgr, bool gcEnabled, SetOfDecls *VisitedCallees);
~ExprEngine();
@@ -339,6 +340,9 @@
void VisitIncrementDecrementOperator(const UnaryOperator* U,
ExplodedNode *Pred,
ExplodedNodeSet &Dst);
+
+ void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred,
+ ExplodedNodeSet &Dst);
void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred,
ExplodedNodeSet & Dst);
@@ -359,9 +363,6 @@
void VisitCXXDeleteExpr(const CXXDeleteExpr *CDE, ExplodedNode *Pred,
ExplodedNodeSet &Dst);
- void VisitAggExpr(const Expr *E, const MemRegion *Dest, ExplodedNode *Pred,
- ExplodedNodeSet &Dst);
-
/// Create a C++ temporary object for an rvalue.
void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME,
ExplodedNode *Pred,
@@ -373,17 +374,7 @@
const CXXThisRegion *getCXXThisRegion(const CXXMethodDecl *decl,
const StackFrameContext *frameCtx);
-
- /// Evaluate arguments with a work list algorithm.
- void evalArguments(ConstExprIterator AI, ConstExprIterator AE,
- const FunctionProtoType *FnType,
- ExplodedNode *Pred, ExplodedNodeSet &Dst,
- bool FstArgAsLValue = false);
-
- /// Evaluate callee expression (for a function call).
- void evalCallee(const CallExpr *callExpr, const ExplodedNodeSet &src,
- ExplodedNodeSet &dest);
-
+
/// evalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic
/// expressions of the form 'x != 0' and generate new nodes (stored in Dst)
/// with those assumptions.
Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h Mon Mar 19 14:02:20 2012
@@ -22,6 +22,7 @@
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Compiler.h"
namespace clang {
namespace ento {
@@ -110,7 +111,7 @@
return Msg->getSuperLoc();
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
if (PE)
return PE->getSourceRange();
return Msg->getSourceRange();
Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h Mon Mar 19 14:02:20 2012
@@ -145,16 +145,16 @@
// Forwarding methods to SymbolManager.
const SymbolConjured* getConjuredSymbol(const Stmt *stmt,
- const LocationContext *LCtx,
- QualType type,
+ const LocationContext *LCtx,
+ QualType type,
unsigned visitCount,
const void *symbolTag = 0) {
return SymMgr.getConjuredSymbol(stmt, LCtx, type, visitCount, symbolTag);
}
const SymbolConjured* getConjuredSymbol(const Expr *expr,
- const LocationContext *LCtx,
- unsigned visitCount,
+ const LocationContext *LCtx,
+ unsigned visitCount,
const void *symbolTag = 0) {
return SymMgr.getConjuredSymbol(expr, LCtx, visitCount, symbolTag);
}
@@ -173,13 +173,18 @@
/// conjured symbols should be used sparingly.
DefinedOrUnknownSVal getConjuredSymbolVal(const void *symbolTag,
const Expr *expr,
- const LocationContext *LCtx,
- unsigned count);
+ const LocationContext *LCtx,
+ unsigned count);
DefinedOrUnknownSVal getConjuredSymbolVal(const void *symbolTag,
const Expr *expr,
- const LocationContext *LCtx,
- QualType type,
+ const LocationContext *LCtx,
+ QualType type,
unsigned count);
+
+ DefinedOrUnknownSVal getConjuredSymbolVal(const Stmt *stmt,
+ const LocationContext *LCtx,
+ QualType type,
+ unsigned visitCount);
DefinedOrUnknownSVal getDerivedRegionValueSymbolVal(
SymbolRef parentSymbol, const TypedValueRegion *region);
Modified: cfe/branches/tooling/lib/ARCMigrate/ARCMT.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/ARCMigrate/ARCMT.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/ARCMigrate/ARCMT.cpp (original)
+++ cfe/branches/tooling/lib/ARCMigrate/ARCMT.cpp Mon Mar 19 14:02:20 2012
@@ -211,7 +211,7 @@
new DiagnosticsEngine(DiagID, &printer, /*ShouldOwnClient=*/false));
Diags->setSourceManager(&PP.getSourceManager());
- printer.BeginSourceFile(PP.getLangOptions(), &PP);
+ printer.BeginSourceFile(PP.getLangOpts(), &PP);
arcDiags.reportDiagnostics(*Diags);
printer.EndSourceFile();
}
@@ -264,7 +264,7 @@
if (Diags->hasFatalErrorOccurred()) {
Diags->Reset();
- DiagClient->BeginSourceFile(Ctx.getLangOptions(), &Unit->getPreprocessor());
+ DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor());
capturedDiags.reportDiagnostics(*Diags);
DiagClient->EndSourceFile();
return true;
@@ -279,7 +279,7 @@
I = capturedDiags.begin(), E = capturedDiags.end(); I != E; ++I)
arcDiags.push_back(*I);
writeARCDiagsToPlist(plistOut, arcDiags,
- Ctx.getSourceManager(), Ctx.getLangOptions());
+ Ctx.getSourceManager(), Ctx.getLangOpts());
}
// After parsing of source files ended, we want to reuse the
@@ -287,7 +287,7 @@
// We call BeginSourceFile because DiagnosticConsumer requires that
// diagnostics with source range information are emitted only in between
// BeginSourceFile() and EndSourceFile().
- DiagClient->BeginSourceFile(Ctx.getLangOptions(), &Unit->getPreprocessor());
+ DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor());
// No macros will be added since we are just checking and we won't modify
// source code.
@@ -573,7 +573,7 @@
if (Diags->hasFatalErrorOccurred()) {
Diags->Reset();
- DiagClient->BeginSourceFile(Ctx.getLangOptions(), &Unit->getPreprocessor());
+ DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor());
capturedDiags.reportDiagnostics(*Diags);
DiagClient->EndSourceFile();
return true;
@@ -584,9 +584,9 @@
// We call BeginSourceFile because DiagnosticConsumer requires that
// diagnostics with source range information are emitted only in between
// BeginSourceFile() and EndSourceFile().
- DiagClient->BeginSourceFile(Ctx.getLangOptions(), &Unit->getPreprocessor());
+ DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor());
- Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOptions());
+ Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts());
TransformActions TA(*Diags, capturedDiags, Ctx, Unit->getPreprocessor());
MigrationPass pass(Ctx, OrigCI.getLangOpts()->getGC(),
Unit->getSema(), TA, ARCMTMacroLocs);
Modified: cfe/branches/tooling/lib/ARCMigrate/ObjCMT.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/ARCMigrate/ObjCMT.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/ARCMigrate/ObjCMT.cpp (original)
+++ cfe/branches/tooling/lib/ARCMigrate/ObjCMT.cpp Mon Mar 19 14:02:20 2012
@@ -58,7 +58,7 @@
virtual void Initialize(ASTContext &Context) {
NSAPIObj.reset(new NSAPI(Context));
Editor.reset(new edit::EditedSource(Context.getSourceManager(),
- Context.getLangOptions(),
+ Context.getLangOpts(),
PPRec));
}
@@ -180,7 +180,7 @@
}
void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) {
- Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOptions());
+ Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts());
RewritesReceiver Rec(rewriter);
Editor->applyRewrites(Rec);
Modified: cfe/branches/tooling/lib/ARCMigrate/TransAutoreleasePool.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/ARCMigrate/TransAutoreleasePool.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/ARCMigrate/TransAutoreleasePool.cpp (original)
+++ cfe/branches/tooling/lib/ARCMigrate/TransAutoreleasePool.cpp Mon Mar 19 14:02:20 2012
@@ -263,10 +263,6 @@
return checkRef(E->getLocation(), E->getDecl()->getLocation());
}
- bool VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
- return checkRef(E->getLocation(), E->getDecl()->getLocation());
- }
-
bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
return checkRef(TL.getBeginLoc(), TL.getTypedefNameDecl()->getLocation());
}
Modified: cfe/branches/tooling/lib/ARCMigrate/TransBlockObjCVariable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/ARCMigrate/TransBlockObjCVariable.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/ARCMigrate/TransBlockObjCVariable.cpp (original)
+++ cfe/branches/tooling/lib/ARCMigrate/TransBlockObjCVariable.cpp Mon Mar 19 14:02:20 2012
@@ -48,13 +48,13 @@
BlockVarChecker(VarDecl *var) : Var(var) { }
bool TraverseImplicitCastExpr(ImplicitCastExpr *castE) {
- if (BlockDeclRefExpr *
- ref = dyn_cast<BlockDeclRefExpr>(castE->getSubExpr())) {
+ if (DeclRefExpr *
+ ref = dyn_cast<DeclRefExpr>(castE->getSubExpr())) {
if (ref->getDecl() == Var) {
if (castE->getCastKind() == CK_LValueToRValue)
return true; // Using the value of the variable.
if (castE->getCastKind() == CK_NoOp && castE->isLValue() &&
- Var->getASTContext().getLangOptions().CPlusPlus)
+ Var->getASTContext().getLangOpts().CPlusPlus)
return true; // Binding to const C++ reference.
}
}
@@ -62,7 +62,7 @@
return base::TraverseImplicitCastExpr(castE);
}
- bool VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
+ bool VisitDeclRefExpr(DeclRefExpr *E) {
if (E->getDecl() == Var)
return false; // The reference of the variable, and not just its value,
// is needed.
Modified: cfe/branches/tooling/lib/ARCMigrate/TransGCAttrs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/ARCMigrate/TransGCAttrs.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/ARCMigrate/TransGCAttrs.cpp (original)
+++ cfe/branches/tooling/lib/ARCMigrate/TransGCAttrs.cpp Mon Mar 19 14:02:20 2012
@@ -97,7 +97,7 @@
bool Invalid = false;
StringRef Spell = Lexer::getSpelling(
SM.getSpellingLoc(TL.getAttrEnumOperandLoc()),
- Buf, SM, Ctx.getLangOptions(), &Invalid);
+ Buf, SM, Ctx.getLangOpts(), &Invalid);
if (Invalid)
return false;
MigrationContext::GCAttrOccurrence::AttrKind Kind;
Modified: cfe/branches/tooling/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/ARCMigrate/TransRetainReleaseDealloc.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/ARCMigrate/TransRetainReleaseDealloc.cpp (original)
+++ cfe/branches/tooling/lib/ARCMigrate/TransRetainReleaseDealloc.cpp Mon Mar 19 14:02:20 2012
@@ -173,7 +173,7 @@
return;
SourceManager &SM = Pass.Ctx.getSourceManager();
StringRef MacroName = Lexer::getImmediateMacroName(Loc, SM,
- Pass.Ctx.getLangOptions());
+ Pass.Ctx.getLangOpts());
bool isGCDOrXPC = llvm::StringSwitch<bool>(MacroName)
.Case("dispatch_retain", true)
.Case("dispatch_release", true)
Modified: cfe/branches/tooling/lib/ARCMigrate/Transforms.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/ARCMigrate/Transforms.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/ARCMigrate/Transforms.cpp (original)
+++ cfe/branches/tooling/lib/ARCMigrate/Transforms.cpp Mon Mar 19 14:02:20 2012
@@ -12,7 +12,6 @@
#include "clang/Sema/SemaDiagnostic.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/StmtVisitor.h"
-#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
#include "clang/Lex/Lexer.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/StringSwitch.h"
@@ -29,51 +28,19 @@
// Helpers.
//===----------------------------------------------------------------------===//
-/// \brief True if the class is one that does not support weak.
-static bool isClassInWeakBlacklist(ObjCInterfaceDecl *cls) {
- if (!cls)
- return false;
-
- bool inList = llvm::StringSwitch<bool>(cls->getName())
- .Case("NSColorSpace", true)
- .Case("NSFont", true)
- .Case("NSFontPanel", true)
- .Case("NSImage", true)
- .Case("NSLazyBrowserCell", true)
- .Case("NSWindow", true)
- .Case("NSWindowController", true)
- .Case("NSViewController", true)
- .Case("NSMenuView", true)
- .Case("NSPersistentUIWindowInfo", true)
- .Case("NSTableCellView", true)
- .Case("NSATSTypeSetter", true)
- .Case("NSATSGlyphStorage", true)
- .Case("NSLineFragmentRenderingContext", true)
- .Case("NSAttributeDictionary", true)
- .Case("NSParagraphStyle", true)
- .Case("NSTextTab", true)
- .Case("NSSimpleHorizontalTypesetter", true)
- .Case("_NSCachedAttributedString", true)
- .Case("NSStringDrawingTextStorage", true)
- .Case("NSTextView", true)
- .Case("NSSubTextStorage", true)
- .Default(false);
-
- if (inList)
- return true;
-
- return isClassInWeakBlacklist(cls->getSuperClass());
-}
-
bool trans::canApplyWeak(ASTContext &Ctx, QualType type,
bool AllowOnUnknownClass) {
- if (!Ctx.getLangOptions().ObjCRuntimeHasWeak)
+ if (!Ctx.getLangOpts().ObjCRuntimeHasWeak)
return false;
QualType T = type;
if (T.isNull())
return false;
+ // iOS is always safe to use 'weak'.
+ if (Ctx.getTargetInfo().getTriple().getOS() == llvm::Triple::IOS)
+ AllowOnUnknownClass = true;
+
while (const PointerType *ptr = T->getAs<PointerType>())
T = ptr->getPointeeType();
if (const ObjCObjectPointerType *ObjT = T->getAs<ObjCObjectPointerType>()) {
@@ -84,8 +51,6 @@
return false; // forward classes are not verifiable, therefore not safe.
if (Class->isArcWeakrefUnavailable())
return false;
- if (isClassInWeakBlacklist(Class))
- return false;
}
return true;
@@ -111,10 +76,10 @@
ASTContext &Ctx) {
SourceManager &SM = Ctx.getSourceManager();
if (loc.isMacroID()) {
- if (!Lexer::isAtEndOfMacroExpansion(loc, SM, Ctx.getLangOptions(), &loc))
+ if (!Lexer::isAtEndOfMacroExpansion(loc, SM, Ctx.getLangOpts(), &loc))
return SourceLocation();
}
- loc = Lexer::getLocForEndOfToken(loc, /*Offset=*/0, SM, Ctx.getLangOptions());
+ loc = Lexer::getLocForEndOfToken(loc, /*Offset=*/0, SM, Ctx.getLangOpts());
// Break down the source location.
std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(loc);
@@ -129,7 +94,7 @@
// Lex from the start of the given location.
Lexer lexer(SM.getLocForStartOfFile(locInfo.first),
- Ctx.getLangOptions(),
+ Ctx.getLangOpts(),
file.begin(), tokenBegin, file.end());
Token tok;
lexer.LexFromRawLexer(tok);
@@ -194,7 +159,6 @@
public:
ReferenceClear(ExprSet &refs) : Refs(refs) { }
bool VisitDeclRefExpr(DeclRefExpr *E) { Refs.erase(E); return true; }
- bool VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { Refs.erase(E); return true; }
};
class ReferenceCollector : public RecursiveASTVisitor<ReferenceCollector> {
@@ -210,12 +174,6 @@
Refs.insert(E);
return true;
}
-
- bool VisitBlockDeclRefExpr(BlockDeclRefExpr *E) {
- if (E->getDecl() == Dcl)
- Refs.insert(E);
- return true;
- }
};
class RemovablesCollector : public RecursiveASTVisitor<RemovablesCollector> {
@@ -382,7 +340,7 @@
// Lex from the start of the given location.
Lexer lexer(SM.getLocForStartOfFile(locInfo.first),
- Pass.Ctx.getLangOptions(),
+ Pass.Ctx.getLangOpts(),
file.begin(), tokenBegin, file.end());
Token tok;
lexer.LexFromRawLexer(tok);
@@ -465,7 +423,7 @@
// Lex from the start of the given location.
Lexer lexer(SM.getLocForStartOfFile(locInfo.first),
- Pass.Ctx.getLangOptions(),
+ Pass.Ctx.getLangOpts(),
file.begin(), tokenBegin, file.end());
Token tok;
lexer.LexFromRawLexer(tok);
@@ -527,7 +485,7 @@
"#if !__has_feature(objc_arc)\n");
CharSourceRange::getTokenRange(FinalizeM->getSourceRange());
const SourceManager &SM = pass.Ctx.getSourceManager();
- const LangOptions &LangOpts = pass.Ctx.getLangOptions();
+ const LangOptions &LangOpts = pass.Ctx.getLangOpts();
bool Invalid;
std::string str = "\n#endif\n";
str += Lexer::getSourceText(
Modified: cfe/branches/tooling/lib/AST/APValue.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/APValue.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/APValue.cpp (original)
+++ cfe/branches/tooling/lib/AST/APValue.cpp Mon Mar 19 14:02:20 2012
@@ -122,74 +122,71 @@
delete Value;
}
-const APValue &APValue::operator=(const APValue &RHS) {
- if (this == &RHS)
- return *this;
- if (Kind != RHS.Kind || Kind == Array || Kind == Struct ||
- Kind == MemberPointer) {
- MakeUninit();
- if (RHS.isInt())
- MakeInt();
- else if (RHS.isFloat())
- MakeFloat();
- else if (RHS.isVector())
- MakeVector();
- else if (RHS.isComplexInt())
- MakeComplexInt();
- else if (RHS.isComplexFloat())
- MakeComplexFloat();
- else if (RHS.isLValue())
- MakeLValue();
- else if (RHS.isArray())
- MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize());
- else if (RHS.isStruct())
- MakeStruct(RHS.getStructNumBases(), RHS.getStructNumFields());
- else if (RHS.isUnion())
- MakeUnion();
- else if (RHS.isMemberPointer())
- MakeMemberPointer(RHS.getMemberPointerDecl(),
- RHS.isMemberPointerToDerivedMember(),
- RHS.getMemberPointerPath());
- else if (RHS.isAddrLabelDiff())
- MakeAddrLabelDiff();
- }
- if (isInt())
+APValue::APValue(const APValue &RHS) : Kind(Uninitialized) {
+ switch (RHS.getKind()) {
+ case Uninitialized:
+ break;
+ case Int:
+ MakeInt();
setInt(RHS.getInt());
- else if (isFloat())
+ break;
+ case Float:
+ MakeFloat();
setFloat(RHS.getFloat());
- else if (isVector())
+ break;
+ case Vector:
+ MakeVector();
setVector(((const Vec *)(const char *)RHS.Data)->Elts,
RHS.getVectorLength());
- else if (isComplexInt())
+ break;
+ case ComplexInt:
+ MakeComplexInt();
setComplexInt(RHS.getComplexIntReal(), RHS.getComplexIntImag());
- else if (isComplexFloat())
+ break;
+ case ComplexFloat:
+ MakeComplexFloat();
setComplexFloat(RHS.getComplexFloatReal(), RHS.getComplexFloatImag());
- else if (isLValue()) {
+ break;
+ case LValue:
+ MakeLValue();
if (RHS.hasLValuePath())
setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(),
RHS.isLValueOnePastTheEnd(), RHS.getLValueCallIndex());
else
setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath(),
RHS.getLValueCallIndex());
- } else if (isArray()) {
+ break;
+ case Array:
+ MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize());
for (unsigned I = 0, N = RHS.getArrayInitializedElts(); I != N; ++I)
getArrayInitializedElt(I) = RHS.getArrayInitializedElt(I);
if (RHS.hasArrayFiller())
getArrayFiller() = RHS.getArrayFiller();
- } else if (isStruct()) {
+ break;
+ case Struct:
+ MakeStruct(RHS.getStructNumBases(), RHS.getStructNumFields());
for (unsigned I = 0, N = RHS.getStructNumBases(); I != N; ++I)
getStructBase(I) = RHS.getStructBase(I);
for (unsigned I = 0, N = RHS.getStructNumFields(); I != N; ++I)
getStructField(I) = RHS.getStructField(I);
- } else if (isUnion()) {
+ break;
+ case Union:
+ MakeUnion();
setUnion(RHS.getUnionField(), RHS.getUnionValue());
- } else if (isAddrLabelDiff()) {
+ break;
+ case MemberPointer:
+ MakeMemberPointer(RHS.getMemberPointerDecl(),
+ RHS.isMemberPointerToDerivedMember(),
+ RHS.getMemberPointerPath());
+ break;
+ case AddrLabelDiff:
+ MakeAddrLabelDiff();
setAddrLabelDiff(RHS.getAddrLabelDiffLHS(), RHS.getAddrLabelDiffRHS());
+ break;
}
- return *this;
}
-void APValue::MakeUninit() {
+void APValue::DestroyDataAndMakeUninit() {
if (Kind == Int)
((APSInt*)(char*)Data)->~APSInt();
else if (Kind == Float)
@@ -215,6 +212,14 @@
Kind = Uninitialized;
}
+void APValue::swap(APValue &RHS) {
+ std::swap(Kind, RHS.Kind);
+ char TmpData[MaxSize];
+ memcpy(TmpData, Data, MaxSize);
+ memcpy(Data, RHS.Data, MaxSize);
+ memcpy(RHS.Data, TmpData, MaxSize);
+}
+
void APValue::dump() const {
dump(llvm::errs());
llvm::errs() << '\n';
Modified: cfe/branches/tooling/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/ASTContext.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/ASTContext.cpp (original)
+++ cfe/branches/tooling/lib/AST/ASTContext.cpp Mon Mar 19 14:02:20 2012
@@ -328,14 +328,14 @@
llvm::errs() << NumImplicitCopyConstructorsDeclared << "/"
<< NumImplicitCopyConstructors
<< " implicit copy constructors created\n";
- if (getLangOptions().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
llvm::errs() << NumImplicitMoveConstructorsDeclared << "/"
<< NumImplicitMoveConstructors
<< " implicit move constructors created\n";
llvm::errs() << NumImplicitCopyAssignmentOperatorsDeclared << "/"
<< NumImplicitCopyAssignmentOperators
<< " implicit copy assignment operators created\n";
- if (getLangOptions().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
llvm::errs() << NumImplicitMoveAssignmentOperatorsDeclared << "/"
<< NumImplicitMoveAssignmentOperators
<< " implicit move assignment operators created\n";
@@ -815,14 +815,24 @@
return getTypeInfoInChars(T.getTypePtr());
}
-/// 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(const Type *T) const {
+ TypeInfoMap::iterator it = MemoizedTypeInfo.find(T);
+ if (it != MemoizedTypeInfo.end())
+ return it->second;
+
+ std::pair<uint64_t, unsigned> Info = getTypeInfoImpl(T);
+ MemoizedTypeInfo.insert(std::make_pair(T, Info));
+ return Info;
+}
+
+/// getTypeInfoImpl - Return the size of the specified type, in bits. This
+/// method does not work on incomplete types.
///
/// FIXME: Pointers into different addr spaces could have different sizes and
/// alignment requirements: getPointerInfo should take an AddrSpace, this
/// should take a QualType, &c.
std::pair<uint64_t, unsigned>
-ASTContext::getTypeInfo(const Type *T) const {
+ASTContext::getTypeInfoImpl(const Type *T) const {
uint64_t Width=0;
unsigned Align=8;
switch (T->getTypeClass()) {
@@ -851,7 +861,8 @@
std::pair<uint64_t, unsigned> EltInfo = getTypeInfo(CAT->getElementType());
uint64_t Size = CAT->getSize().getZExtValue();
- assert((Size == 0 || EltInfo.first <= (uint64_t)(-1)/Size) && "Overflow in array type bit size evaluation");
+ assert((Size == 0 || EltInfo.first <= (uint64_t)(-1)/Size) &&
+ "Overflow in array type bit size evaluation");
Width = EltInfo.first*Size;
Align = EltInfo.second;
Width = llvm::RoundUpToAlignment(Width, Align);
@@ -3179,7 +3190,7 @@
return true;
}
- if (getLangOptions().ObjC1) {
+ if (getLangOpts().ObjC1) {
const ObjCObjectPointerType *T1OPType = T1->getAs<ObjCObjectPointerType>(),
*T2OPType = T2->getAs<ObjCObjectPointerType>();
if (T1OPType && T2OPType) {
@@ -3758,7 +3769,7 @@
CreateRecordDecl(const ASTContext &Ctx, RecordDecl::TagKind TK,
DeclContext *DC, IdentifierInfo *Id) {
SourceLocation Loc;
- if (Ctx.getLangOptions().CPlusPlus)
+ if (Ctx.getLangOpts().CPlusPlus)
return CXXRecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id);
else
return RecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id);
@@ -3893,7 +3904,7 @@
bool ASTContext::BlockRequiresCopying(QualType Ty) const {
if (Ty->isObjCRetainableType())
return true;
- if (getLangOptions().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
if (const RecordType *RT = Ty->getAs<RecordType>()) {
CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
return RD->hasConstCopyConstructor();
@@ -4369,7 +4380,7 @@
// information is not especially sensible, but we're stuck with it for
// compatibility with GCC, although providing it breaks anything that
// actually uses runtime introspection and wants to work on both runtimes...
- if (!Ctx->getLangOptions().NeXTRuntime) {
+ if (!Ctx->getLangOpts().NeXTRuntime) {
const RecordDecl *RD = FD->getParent();
const ASTRecordLayout &RL = Ctx->getASTRecordLayout(RD);
S += llvm::utostr(RL.getFieldOffset(FD->getFieldIndex()));
@@ -5107,10 +5118,10 @@
/// garbage collection attribute.
///
Qualifiers::GC ASTContext::getObjCGCAttrKind(QualType Ty) const {
- if (getLangOptions().getGC() == LangOptions::NonGC)
+ if (getLangOpts().getGC() == LangOptions::NonGC)
return Qualifiers::GCNone;
- assert(getLangOptions().ObjC1);
+ assert(getLangOpts().ObjC1);
Qualifiers::GC GCAttrs = Ty.getObjCGCAttr();
// Default behaviour under objective-C's gc is for ObjC pointers
@@ -5604,7 +5615,7 @@
/// same. See 6.7.[2,3,5] for additional rules.
bool ASTContext::typesAreCompatible(QualType LHS, QualType RHS,
bool CompareUnqualified) {
- if (getLangOptions().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
return hasSameType(LHS, RHS);
return !mergeTypes(LHS, RHS, false, CompareUnqualified).isNull();
@@ -6557,7 +6568,7 @@
if (!FD->isInlined())
return External;
- if (!getLangOptions().CPlusPlus || FD->hasAttr<GNUInlineAttr>()) {
+ if (!getLangOpts().CPlusPlus || FD->hasAttr<GNUInlineAttr>()) {
// GNU or C99 inline semantics. Determine whether this symbol should be
// externally visible.
if (FD->isInlineDefinitionExternallyVisible())
@@ -6589,7 +6600,7 @@
TSK = VD->getTemplateSpecializationKind();
Linkage L = VD->getLinkage();
- if (L == ExternalLinkage && getLangOptions().CPlusPlus &&
+ if (L == ExternalLinkage && getLangOpts().CPlusPlus &&
VD->getType()->getLinkage() == UniqueExternalLinkage)
L = UniqueExternalLinkage;
Modified: cfe/branches/tooling/lib/AST/ASTDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/ASTDiagnostic.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/ASTDiagnostic.cpp (original)
+++ cfe/branches/tooling/lib/AST/ASTDiagnostic.cpp Mon Mar 19 14:02:20 2012
@@ -164,6 +164,8 @@
for (unsigned I = 0, E = QualTypeVals.size(); I != E; ++I) {
QualType CompareTy =
QualType::getFromOpaquePtr(reinterpret_cast<void*>(QualTypeVals[I]));
+ if (CompareTy.isNull())
+ continue;
if (CompareTy == Ty)
continue; // Same types
QualType CompareCanTy = CompareTy.getCanonicalType();
@@ -292,7 +294,7 @@
if (DC->isTranslationUnit()) {
// FIXME: Get these strings from some localized place
- if (Context.getLangOptions().CPlusPlus)
+ if (Context.getLangOpts().CPlusPlus)
S = "the global namespace";
else
S = "the global scope";
Modified: cfe/branches/tooling/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/ASTImporter.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/ASTImporter.cpp (original)
+++ cfe/branches/tooling/lib/AST/ASTImporter.cpp Mon Mar 19 14:02:20 2012
@@ -965,10 +965,10 @@
Base1->getType(), Base2->getType())) {
Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
<< Context.C2.getTypeDeclType(D2);
- Context.Diag2(Base2->getSourceRange().getBegin(), diag::note_odr_base)
+ Context.Diag2(Base2->getLocStart(), diag::note_odr_base)
<< Base2->getType()
<< Base2->getSourceRange();
- Context.Diag1(Base1->getSourceRange().getBegin(), diag::note_odr_base)
+ Context.Diag1(Base1->getLocStart(), diag::note_odr_base)
<< Base1->getType()
<< Base1->getSourceRange();
return false;
@@ -978,10 +978,10 @@
if (Base1->isVirtual() != Base2->isVirtual()) {
Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
<< Context.C2.getTypeDeclType(D2);
- Context.Diag2(Base2->getSourceRange().getBegin(),
+ Context.Diag2(Base2->getLocStart(),
diag::note_odr_virtual_base)
<< Base2->isVirtual() << Base2->getSourceRange();
- Context.Diag1(Base1->getSourceRange().getBegin(), diag::note_odr_base)
+ Context.Diag1(Base1->getLocStart(), diag::note_odr_base)
<< Base1->isVirtual()
<< Base1->getSourceRange();
return false;
@@ -991,7 +991,7 @@
Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
<< Context.C2.getTypeDeclType(D2);
const CXXBaseSpecifier *Base1 = D1CXX->bases_begin();
- Context.Diag1(Base1->getSourceRange().getBegin(), diag::note_odr_base)
+ Context.Diag1(Base1->getLocStart(), diag::note_odr_base)
<< Base1->getType()
<< Base1->getSourceRange();
Context.Diag2(D2->getLocation(), diag::note_odr_missing_base);
@@ -1359,7 +1359,7 @@
// The context we're importing from has an unsigned 'char'. If we're
// importing into a context with a signed 'char', translate to
// 'unsigned char' instead.
- if (Importer.getToContext().getLangOptions().CharIsSigned)
+ if (Importer.getToContext().getLangOpts().CharIsSigned)
return Importer.getToContext().UnsignedCharTy;
return Importer.getToContext().CharTy;
@@ -1368,7 +1368,7 @@
// The context we're importing from has an unsigned 'char'. If we're
// importing into a context with a signed 'char', translate to
// 'unsigned char' instead.
- if (!Importer.getToContext().getLangOptions().CharIsSigned)
+ if (!Importer.getToContext().getLangOpts().CharIsSigned)
return Importer.getToContext().SignedCharTy;
return Importer.getToContext().CharTy;
@@ -2243,7 +2243,7 @@
if (!SearchName && D->getTypedefNameForAnonDecl()) {
SearchName = Importer.Import(D->getTypedefNameForAnonDecl()->getDeclName());
IDNS = Decl::IDNS_Ordinary;
- } else if (Importer.getToContext().getLangOptions().CPlusPlus)
+ } else if (Importer.getToContext().getLangOpts().CPlusPlus)
IDNS |= Decl::IDNS_Ordinary;
// We may already have an enum of the same name; try to find and match it.
@@ -2328,7 +2328,7 @@
if (!SearchName && D->getTypedefNameForAnonDecl()) {
SearchName = Importer.Import(D->getTypedefNameForAnonDecl()->getDeclName());
IDNS = Decl::IDNS_Ordinary;
- } else if (Importer.getToContext().getLangOptions().CPlusPlus)
+ } else if (Importer.getToContext().getLangOpts().CPlusPlus)
IDNS |= Decl::IDNS_Ordinary;
// We may already have a record of the same name; try to find and match it.
@@ -2485,7 +2485,7 @@
// Sema::IsOverload out to the AST library.
// Function overloading is okay in C++.
- if (Importer.getToContext().getLangOptions().CPlusPlus)
+ if (Importer.getToContext().getLangOpts().CPlusPlus)
continue;
// Complain about inconsistent function types.
@@ -3947,6 +3947,7 @@
Importer.Import(E->getQualifierLoc()),
Importer.Import(E->getTemplateKeywordLoc()),
ToD,
+ E->refersToEnclosingLocal(),
Importer.Import(E->getLocation()),
T, E->getValueKind(),
FoundD,
@@ -4171,7 +4172,7 @@
return 0;
return ToContext.getTrivialTypeSourceInfo(T,
- FromTSI->getTypeLoc().getSourceRange().getBegin());
+ FromTSI->getTypeLoc().getLocStart());
}
Decl *ASTImporter::Import(Decl *FromD) {
Modified: cfe/branches/tooling/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/Decl.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/Decl.cpp (original)
+++ cfe/branches/tooling/lib/AST/Decl.cpp Mon Mar 19 14:02:20 2012
@@ -222,7 +222,7 @@
// and neither explicitly declared extern nor previously
// declared to have external linkage; or
// (there is no equivalent in C99)
- if (Context.getLangOptions().CPlusPlus &&
+ if (Context.getLangOpts().CPlusPlus &&
Var->getType().isConstant(Context) &&
Var->getStorageClass() != SC_Extern &&
Var->getStorageClass() != SC_PrivateExtern) {
@@ -279,7 +279,7 @@
// scope and no storage-class specifier, its linkage is
// external.
LinkageInfo LV;
- LV.mergeVisibility(Context.getLangOptions().getVisibilityMode());
+ LV.mergeVisibility(Context.getLangOpts().getVisibilityMode());
if (F.ConsiderVisibilityAttributes) {
if (llvm::Optional<Visibility> Vis = D->getExplicitVisibility()) {
@@ -330,19 +330,19 @@
//
// Note that we don't want to make the variable non-external
// because of this, but unique-external linkage suits us.
- if (Context.getLangOptions().CPlusPlus &&
+ if (Context.getLangOpts().CPlusPlus &&
!Var->getDeclContext()->isExternCContext()) {
LinkageInfo TypeLV = getLVForType(Var->getType());
if (TypeLV.linkage() != ExternalLinkage)
return LinkageInfo::uniqueExternal();
- if (!LV.visibilityExplicit())
- LV.mergeVisibility(TypeLV.visibility(), TypeLV.visibilityExplicit());
+ LV.mergeVisibilityWithMin(TypeLV.visibility(),
+ TypeLV.visibilityExplicit());
}
if (Var->getStorageClass() == SC_PrivateExtern)
LV.setVisibility(HiddenVisibility, true);
- if (!Context.getLangOptions().CPlusPlus &&
+ if (!Context.getLangOpts().CPlusPlus &&
(Var->getStorageClass() == SC_Extern ||
Var->getStorageClass() == SC_PrivateExtern)) {
@@ -377,7 +377,7 @@
// storage-class specifier, its linkage is determined exactly
// as if it were declared with the storage-class specifier
// extern.
- if (!Context.getLangOptions().CPlusPlus &&
+ if (!Context.getLangOpts().CPlusPlus &&
(Function->getStorageClass() == SC_Extern ||
Function->getStorageClass() == SC_PrivateExtern ||
Function->getStorageClass() == SC_None)) {
@@ -401,7 +401,7 @@
// unique-external linkage, it's not legally usable from outside
// this translation unit. However, we should use the C linkage
// rules instead for extern "C" declarations.
- if (Context.getLangOptions().CPlusPlus &&
+ if (Context.getLangOpts().CPlusPlus &&
!Function->getDeclContext()->isExternCContext() &&
Function->getType()->getLinkage() == UniqueExternalLinkage)
return LinkageInfo::uniqueExternal();
@@ -447,7 +447,7 @@
// Consider -fvisibility unless the type has C linkage.
if (F.ConsiderGlobalVisibility)
F.ConsiderGlobalVisibility =
- (Context.getLangOptions().CPlusPlus &&
+ (Context.getLangOpts().CPlusPlus &&
!Tag->getDeclContext()->isExternCContext());
// - an enumerator belonging to an enumeration with external linkage;
@@ -499,7 +499,7 @@
return LinkageInfo::none();
LinkageInfo LV;
- LV.mergeVisibility(D->getASTContext().getLangOptions().getVisibilityMode());
+ LV.mergeVisibility(D->getASTContext().getLangOpts().getVisibilityMode());
// The flags we're going to use to compute the class's visibility.
LVFlags ClassF = F;
@@ -563,7 +563,7 @@
if (TSK != TSK_ExplicitInstantiationDeclaration &&
TSK != TSK_ExplicitInstantiationDefinition &&
F.ConsiderGlobalVisibility &&
- MD->getASTContext().getLangOptions().InlineVisibilityHidden) {
+ MD->getASTContext().getLangOpts().InlineVisibilityHidden) {
// InlineVisibilityHidden only applies to definitions, and
// isInlined() only gives meaningful answers on definitions
// anyway.
@@ -845,7 +845,7 @@
}
std::string NamedDecl::getQualifiedNameAsString() const {
- return getQualifiedNameAsString(getASTContext().getLangOptions());
+ return getQualifiedNameAsString(getASTContext().getLangOpts());
}
std::string NamedDecl::getQualifiedNameAsString(const PrintingPolicy &P) const {
@@ -985,15 +985,13 @@
NamedDecl *NamedDecl::getUnderlyingDeclImpl() {
NamedDecl *ND = this;
- while (true) {
- if (UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(ND))
- ND = UD->getTargetDecl();
- else if (ObjCCompatibleAliasDecl *AD
- = dyn_cast<ObjCCompatibleAliasDecl>(ND))
- return AD->getClassInterface();
- else
- return ND;
- }
+ while (UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(ND))
+ ND = UD->getTargetDecl();
+
+ if (ObjCCompatibleAliasDecl *AD = dyn_cast<ObjCCompatibleAliasDecl>(ND))
+ return AD->getClassInterface();
+
+ return ND;
}
bool NamedDecl::isCXXInstanceMember() const {
@@ -1209,7 +1207,7 @@
return false;
ASTContext &Context = getASTContext();
- if (!Context.getLangOptions().CPlusPlus)
+ if (!Context.getLangOpts().CPlusPlus)
return true;
return DC->isExternCContext();
}
@@ -1218,7 +1216,9 @@
return getFirstDeclaration();
}
-VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition() const {
+VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition(
+ ASTContext &C) const
+{
// C++ [basic.def]p2:
// A declaration is a definition unless [...] it contains the 'extern'
// specifier or a linkage-specification and neither an initializer [...],
@@ -1260,7 +1260,7 @@
// and without a storage class specifier or the scs 'static', constitutes
// a tentative definition.
// No such thing in C++.
- if (!getASTContext().getLangOptions().CPlusPlus && isFileVarDecl())
+ if (!C.getLangOpts().CPlusPlus && isFileVarDecl())
return TentativeDefinition;
// What's left is (in C, block-scope) declarations without initializers or
@@ -1298,23 +1298,23 @@
return true;
}
-VarDecl *VarDecl::getDefinition() {
+VarDecl *VarDecl::getDefinition(ASTContext &C) {
VarDecl *First = getFirstDeclaration();
for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end();
I != E; ++I) {
- if ((*I)->isThisDeclarationADefinition() == Definition)
+ if ((*I)->isThisDeclarationADefinition(C) == Definition)
return *I;
}
return 0;
}
-VarDecl::DefinitionKind VarDecl::hasDefinition() const {
+VarDecl::DefinitionKind VarDecl::hasDefinition(ASTContext &C) const {
DefinitionKind Kind = DeclarationOnly;
const VarDecl *First = getFirstDeclaration();
for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end();
I != E; ++I) {
- Kind = std::max(Kind, (*I)->isThisDeclarationADefinition());
+ Kind = std::max(Kind, (*I)->isThisDeclarationADefinition(C));
if (Kind == Definition)
break;
}
@@ -1372,8 +1372,8 @@
Init = I;
}
-bool VarDecl::isUsableInConstantExpressions() const {
- const LangOptions &Lang = getASTContext().getLangOptions();
+bool VarDecl::isUsableInConstantExpressions(ASTContext &C) const {
+ const LangOptions &Lang = C.getLangOpts();
if (!Lang.CPlusPlus)
return false;
@@ -1452,7 +1452,7 @@
// In C++11, we have determined whether the initializer was a constant
// expression as a side-effect.
- if (getASTContext().getLangOptions().CPlusPlus0x && !Eval->CheckedICE) {
+ if (getASTContext().getLangOpts().CPlusPlus0x && !Eval->CheckedICE) {
Eval->CheckedICE = true;
Eval->IsICE = Result && Notes.empty();
}
@@ -1476,7 +1476,7 @@
// In C++11, evaluate the initializer to check whether it's a constant
// expression.
- if (getASTContext().getLangOptions().CPlusPlus0x) {
+ if (getASTContext().getLangOpts().CPlusPlus0x) {
llvm::SmallVector<PartialDiagnosticAt, 8> Notes;
evaluateValue(Notes);
return Eval->IsICE;
@@ -1693,7 +1693,7 @@
const TranslationUnitDecl *tunit =
dyn_cast<TranslationUnitDecl>(getDeclContext()->getRedeclContext());
return tunit &&
- !tunit->getASTContext().getLangOptions().Freestanding &&
+ !tunit->getASTContext().getLangOpts().Freestanding &&
getIdentifier() &&
getIdentifier()->isStr("main");
}
@@ -1732,7 +1732,7 @@
return false;
ASTContext &Context = getASTContext();
- if (!Context.getLangOptions().CPlusPlus)
+ if (!Context.getLangOpts().CPlusPlus)
return true;
return isMain() || DC->isExternCContext();
@@ -1820,7 +1820,7 @@
// If this function is at translation-unit scope and we're not in
// C++, it refers to the C library function.
- if (!Context.getLangOptions().CPlusPlus &&
+ if (!Context.getLangOpts().CPlusPlus &&
getDeclContext()->isTranslationUnit())
return BuiltinID;
@@ -1875,7 +1875,7 @@
/// function parameters, if some of the parameters have default
/// arguments (in C++) or the last parameter is a parameter pack.
unsigned FunctionDecl::getMinRequiredArguments() const {
- if (!getASTContext().getLangOptions().CPlusPlus)
+ if (!getASTContext().getLangOpts().CPlusPlus)
return getNumParams();
unsigned NumRequiredArgs = getNumParams();
@@ -1965,7 +1965,7 @@
ASTContext &Context = getASTContext();
- if (Context.getLangOptions().GNUInline || hasAttr<GNUInlineAttr>()) {
+ if (Context.getLangOpts().GNUInline || hasAttr<GNUInlineAttr>()) {
// With GNU inlining, a declaration with 'inline' but not 'extern', forces
// an externally visible definition.
//
@@ -1993,7 +1993,7 @@
return FoundBody;
}
- if (Context.getLangOptions().CPlusPlus)
+ if (Context.getLangOpts().CPlusPlus)
return false;
// C99 6.7.4p6:
@@ -2034,7 +2034,7 @@
assert(isInlined() && "Function must be inline");
ASTContext &Context = getASTContext();
- if (Context.getLangOptions().GNUInline || hasAttr<GNUInlineAttr>()) {
+ if (Context.getLangOpts().GNUInline || hasAttr<GNUInlineAttr>()) {
// Note: If you change the logic here, please change
// doesDeclarationForceExternallyVisibleDefinition as well.
//
@@ -2674,6 +2674,19 @@
TagDecl::completeDefinition();
}
+EnumDecl *EnumDecl::getInstantiatedFromMemberEnum() const {
+ if (SpecializationInfo)
+ return cast<EnumDecl>(SpecializationInfo->getInstantiatedFrom());
+
+ return 0;
+}
+
+void EnumDecl::setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED,
+ TemplateSpecializationKind TSK) {
+ assert(!SpecializationInfo && "Member enum is already a specialization");
+ SpecializationInfo = new (C) MemberSpecializationInfo(ED, TSK);
+}
+
//===----------------------------------------------------------------------===//
// RecordDecl Implementation
//===----------------------------------------------------------------------===//
Modified: cfe/branches/tooling/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/DeclBase.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/DeclBase.cpp (original)
+++ cfe/branches/tooling/lib/AST/DeclBase.cpp Mon Mar 19 14:02:20 2012
@@ -69,7 +69,7 @@
void Decl::setInvalidDecl(bool Invalid) {
InvalidDecl = Invalid;
- if (Invalid) {
+ if (Invalid && !isa<ParmVarDecl>(this)) {
// Defensive maneuver for ill-formed code: we're likely not to make it to
// a point where we set the access specifier, so default it to "public"
// to avoid triggering asserts elsewhere in the front end.
@@ -423,7 +423,7 @@
}
} else if (isa<ObjCPropertyDecl>(this) || isa<ObjCMethodDecl>(this))
return false;
- else if (!(getASTContext().getLangOptions().ObjCNonFragileABI &&
+ else if (!(getASTContext().getLangOpts().ObjCNonFragileABI &&
isa<ObjCInterfaceDecl>(this)))
return false;
@@ -938,7 +938,7 @@
DeclarationName Name) {
ASTContext &Context = DC->getParentASTContext();
StoredDeclsMap *Map;
- if (!(Map = DC->LookupPtr))
+ if (!(Map = DC->LookupPtr.getPointer()))
Map = DC->CreateStoredDeclsMap(Context);
StoredDeclsList &List = (*Map)[Name];
@@ -955,7 +955,7 @@
ASTContext &Context = DC->getParentASTContext();;
StoredDeclsMap *Map;
- if (!(Map = DC->LookupPtr))
+ if (!(Map = DC->LookupPtr.getPointer()))
Map = DC->CreateStoredDeclsMap(Context);
StoredDeclsList &List = (*Map)[Name];
@@ -1032,7 +1032,7 @@
// Remove only decls that have a name
if (!ND->getDeclName()) return;
- StoredDeclsMap *Map = getPrimaryContext()->LookupPtr;
+ StoredDeclsMap *Map = getPrimaryContext()->LookupPtr.getPointer();
if (!Map) return;
StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName());
@@ -1072,53 +1072,105 @@
addHiddenDecl(D);
if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
- ND->getDeclContext()->makeDeclVisibleInContext(ND);
+ ND->getDeclContext()->getPrimaryContext()->
+ makeDeclVisibleInContextWithFlags(ND, false, true);
}
void DeclContext::addDeclInternal(Decl *D) {
addHiddenDecl(D);
if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
- ND->getDeclContext()->makeDeclVisibleInContextInternal(ND);
+ ND->getDeclContext()->getPrimaryContext()->
+ makeDeclVisibleInContextWithFlags(ND, true, true);
+}
+
+/// shouldBeHidden - Determine whether a declaration which was declared
+/// within its semantic context should be invisible to qualified name lookup.
+static bool shouldBeHidden(NamedDecl *D) {
+ // Skip unnamed declarations.
+ if (!D->getDeclName())
+ return true;
+
+ // Skip entities that can't be found by name lookup into a particular
+ // context.
+ if ((D->getIdentifierNamespace() == 0 && !isa<UsingDirectiveDecl>(D)) ||
+ D->isTemplateParameter())
+ return true;
+
+ // Skip template specializations.
+ // FIXME: This feels like a hack. Should DeclarationName support
+ // template-ids, or is there a better way to keep specializations
+ // from being visible?
+ if (isa<ClassTemplateSpecializationDecl>(D))
+ return true;
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ if (FD->isFunctionTemplateSpecialization())
+ return true;
+
+ return false;
}
/// buildLookup - Build the lookup data structure with all of the
-/// declarations in DCtx (and any other contexts linked to it or
-/// transparent contexts nested within it).
-void DeclContext::buildLookup(DeclContext *DCtx) {
+/// declarations in this DeclContext (and any other contexts linked
+/// to it or transparent contexts nested within it) and return it.
+StoredDeclsMap *DeclContext::buildLookup() {
+ assert(this == getPrimaryContext() && "buildLookup called on non-primary DC");
+
+ if (!LookupPtr.getInt())
+ return LookupPtr.getPointer();
+
llvm::SmallVector<DeclContext *, 2> Contexts;
- DCtx->collectAllContexts(Contexts);
- for (unsigned I = 0, N = Contexts.size(); I != N; ++I) {
- for (decl_iterator D = Contexts[I]->decls_begin(),
- DEnd = Contexts[I]->decls_end();
- D != DEnd; ++D) {
- // Insert this declaration into the lookup structure, but only
- // if it's semantically in its decl context. During non-lazy
- // lookup building, this is implicitly enforced by addDecl.
- if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
- if (D->getDeclContext() == Contexts[I])
- makeDeclVisibleInContextImpl(ND, false);
-
- // If this declaration is itself a transparent declaration context or
- // inline namespace, add its members (recursively).
- if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D))
- if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace())
- buildLookup(InnerCtx->getPrimaryContext());
- }
+ collectAllContexts(Contexts);
+ for (unsigned I = 0, N = Contexts.size(); I != N; ++I)
+ buildLookupImpl(Contexts[I]);
+
+ // We no longer have any lazy decls.
+ LookupPtr.setInt(false);
+ return LookupPtr.getPointer();
+}
+
+/// buildLookupImpl - Build part of the lookup data structure for the
+/// declarations contained within DCtx, which will either be this
+/// DeclContext, a DeclContext linked to it, or a transparent context
+/// nested within it.
+void DeclContext::buildLookupImpl(DeclContext *DCtx) {
+ for (decl_iterator I = DCtx->decls_begin(), E = DCtx->decls_end();
+ I != E; ++I) {
+ Decl *D = *I;
+
+ // Insert this declaration into the lookup structure, but only if
+ // it's semantically within its decl context. Any other decls which
+ // should be found in this context are added eagerly.
+ if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
+ if (ND->getDeclContext() == DCtx && !shouldBeHidden(ND))
+ makeDeclVisibleInContextImpl(ND, false);
+
+ // If this declaration is itself a transparent declaration context
+ // or inline namespace, add the members of this declaration of that
+ // context (recursively).
+ if (DeclContext *InnerCtx = dyn_cast<DeclContext>(D))
+ if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace())
+ buildLookupImpl(InnerCtx);
}
}
DeclContext::lookup_result
DeclContext::lookup(DeclarationName Name) {
+ assert(DeclKind != Decl::LinkageSpec &&
+ "Should not perform lookups into linkage specs!");
+
DeclContext *PrimaryContext = getPrimaryContext();
if (PrimaryContext != this)
return PrimaryContext->lookup(Name);
if (hasExternalVisibleStorage()) {
- // Check to see if we've already cached the lookup results.
- if (LookupPtr) {
- StoredDeclsMap::iterator I = LookupPtr->find(Name);
- if (I != LookupPtr->end())
+ // If a PCH has a result for this name, and we have a local declaration, we
+ // will have imported the PCH result when adding the local declaration.
+ // FIXME: For modules, we could have had more declarations added by module
+ // imoprts since we saw the declaration of the local name.
+ if (StoredDeclsMap *Map = LookupPtr.getPointer()) {
+ StoredDeclsMap::iterator I = Map->find(Name);
+ if (I != Map->end())
return I->second.getLookupResult();
}
@@ -1126,20 +1178,18 @@
return Source->FindExternalVisibleDeclsByName(this, Name);
}
- /// If there is no lookup data structure, build one now by walking
- /// all of the linked DeclContexts (in declaration order!) and
- /// inserting their values.
- if (!LookupPtr) {
- buildLookup(this);
+ StoredDeclsMap *Map = LookupPtr.getPointer();
+ if (LookupPtr.getInt())
+ Map = buildLookup();
- if (!LookupPtr)
- return lookup_result(lookup_iterator(0), lookup_iterator(0));
- }
+ if (!Map)
+ return lookup_result(lookup_iterator(0), lookup_iterator(0));
- StoredDeclsMap::iterator Pos = LookupPtr->find(Name);
- if (Pos == LookupPtr->end())
+ StoredDeclsMap::iterator I = Map->find(Name);
+ if (I == Map->end())
return lookup_result(lookup_iterator(0), lookup_iterator(0));
- return Pos->second.getLookupResult();
+
+ return I->second.getLookupResult();
}
DeclContext::lookup_const_result
@@ -1160,10 +1210,10 @@
}
// If we have a lookup table, check there first. Maybe we'll get lucky.
- if (LookupPtr) {
- StoredDeclsMap::iterator Pos = LookupPtr->find(Name);
- if (Pos != LookupPtr->end()) {
- Results.insert(Results.end(),
+ if (StoredDeclsMap *Map = LookupPtr.getPointer()) {
+ StoredDeclsMap::iterator Pos = Map->find(Name);
+ if (Pos != Map->end()) {
+ Results.insert(Results.end(),
Pos->second.getLookupResult().first,
Pos->second.getLookupResult().second);
return;
@@ -1213,66 +1263,73 @@
return false;
}
-void DeclContext::makeDeclVisibleInContext(NamedDecl *D, bool Recoverable)
-{
- makeDeclVisibleInContextWithFlags(D, false, Recoverable);
-}
-
-void DeclContext::makeDeclVisibleInContextInternal(NamedDecl *D, bool Recoverable)
-{
- makeDeclVisibleInContextWithFlags(D, true, Recoverable);
-}
-
-void DeclContext::makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal, bool Recoverable) {
- // FIXME: This feels like a hack. Should DeclarationName support
- // template-ids, or is there a better way to keep specializations
- // from being visible?
- if (isa<ClassTemplateSpecializationDecl>(D) || D->isTemplateParameter())
+void DeclContext::makeDeclVisibleInContext(NamedDecl *D) {
+ DeclContext *PrimaryDC = this->getPrimaryContext();
+ DeclContext *DeclDC = D->getDeclContext()->getPrimaryContext();
+ // If the decl is being added outside of its semantic decl context, we
+ // need to ensure that we eagerly build the lookup information for it.
+ PrimaryDC->makeDeclVisibleInContextWithFlags(D, false, PrimaryDC == DeclDC);
+}
+
+void DeclContext::makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal,
+ bool Recoverable) {
+ assert(this == getPrimaryContext() && "expected a primary DC");
+
+ // Skip declarations within functions.
+ // FIXME: We shouldn't need to build lookup tables for function declarations
+ // ever, and we can't do so correctly because we can't model the nesting of
+ // scopes which occurs within functions. We use "qualified" lookup into
+ // function declarations when handling friend declarations inside nested
+ // classes, and consequently accept the following invalid code:
+ //
+ // void f() { void g(); { int g; struct S { friend void g(); }; } }
+ if (isFunctionOrMethod() && !isa<FunctionDecl>(D))
return;
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
- if (FD->isFunctionTemplateSpecialization())
- return;
- DeclContext *PrimaryContext = getPrimaryContext();
- if (PrimaryContext != this) {
- PrimaryContext->makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
+ // Skip declarations which should be invisible to name lookup.
+ if (shouldBeHidden(D))
return;
- }
- // If we already have a lookup data structure, perform the insertion
- // into it. If we haven't deserialized externally stored decls, deserialize
- // them so we can add the decl. Otherwise, be lazy and don't build that
- // structure until someone asks for it.
- if (LookupPtr || !Recoverable || hasExternalVisibleStorage())
+ // If we already have a lookup data structure, perform the insertion into
+ // it. If we might have externally-stored decls with this name, look them
+ // up and perform the insertion. If this decl was declared outside its
+ // semantic context, buildLookup won't add it, so add it now.
+ //
+ // FIXME: As a performance hack, don't add such decls into the translation
+ // unit unless we're in C++, since qualified lookup into the TU is never
+ // performed.
+ if (LookupPtr.getPointer() || hasExternalVisibleStorage() ||
+ ((!Recoverable || D->getDeclContext() != D->getLexicalDeclContext()) &&
+ (getParentASTContext().getLangOpts().CPlusPlus ||
+ !isTranslationUnit()))) {
+ // If we have lazily omitted any decls, they might have the same name as
+ // the decl which we are adding, so build a full lookup table before adding
+ // this decl.
+ buildLookup();
makeDeclVisibleInContextImpl(D, Internal);
+ } else {
+ LookupPtr.setInt(true);
+ }
// If we are a transparent context or inline namespace, insert into our
// parent context, too. This operation is recursive.
if (isTransparentContext() || isInlineNamespace())
- getParent()->makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
+ getParent()->getPrimaryContext()->
+ makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
Decl *DCAsDecl = cast<Decl>(this);
- // Notify that a decl was made visible unless it's a Tag being defined.
+ // Notify that a decl was made visible unless we are a Tag being defined.
if (!(isa<TagDecl>(DCAsDecl) && cast<TagDecl>(DCAsDecl)->isBeingDefined()))
if (ASTMutationListener *L = DCAsDecl->getASTMutationListener())
L->AddedVisibleDecl(this, D);
}
void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal) {
- // Skip unnamed declarations.
- if (!D->getDeclName())
- return;
-
- // Skip entities that can't be found by name lookup into a particular
- // context.
- if ((D->getIdentifierNamespace() == 0 && !isa<UsingDirectiveDecl>(D)) ||
- D->isTemplateParameter())
- return;
-
- ASTContext *C = 0;
- if (!LookupPtr) {
- C = &getParentASTContext();
- CreateStoredDeclsMap(*C);
+ // Find or create the stored declaration map.
+ StoredDeclsMap *Map = LookupPtr.getPointer();
+ if (!Map) {
+ ASTContext *C = &getParentASTContext();
+ Map = CreateStoredDeclsMap(*C);
}
// If there is an external AST source, load any declarations it knows about
@@ -1282,21 +1339,21 @@
if (!Internal)
if (ExternalASTSource *Source = getParentASTContext().getExternalSource())
if (hasExternalVisibleStorage() &&
- LookupPtr->find(D->getDeclName()) == LookupPtr->end())
+ Map->find(D->getDeclName()) == Map->end())
Source->FindExternalVisibleDeclsByName(this, D->getDeclName());
// Insert this declaration into the map.
- StoredDeclsList &DeclNameEntries = (*LookupPtr)[D->getDeclName()];
+ StoredDeclsList &DeclNameEntries = (*Map)[D->getDeclName()];
if (DeclNameEntries.isNull()) {
DeclNameEntries.setOnlyValue(D);
return;
}
- // If it is possible that this is a redeclaration, check to see if there is
- // already a decl for which declarationReplaces returns true. If there is
- // one, just replace it and return.
- if (DeclNameEntries.HandleRedeclaration(D))
+ if (DeclNameEntries.HandleRedeclaration(D)) {
+ // This declaration has replaced an existing one for which
+ // declarationReplaces returns true.
return;
+ }
// Put this declaration into the appropriate slot.
DeclNameEntries.AddSubsequentDecl(D);
@@ -1306,6 +1363,8 @@
/// this context.
DeclContext::udir_iterator_range
DeclContext::getUsingDirectives() const {
+ // FIXME: Use something more efficient than normal lookup for using
+ // directives. In C++, using directives are looked up more than anything else.
lookup_const_result Result = lookup(UsingDirectiveDecl::getName());
return udir_iterator_range(reinterpret_cast<udir_iterator>(Result.first),
reinterpret_cast<udir_iterator>(Result.second));
@@ -1316,7 +1375,7 @@
//===----------------------------------------------------------------------===//
StoredDeclsMap *DeclContext::CreateStoredDeclsMap(ASTContext &C) const {
- assert(!LookupPtr && "context already has a decls map");
+ assert(!LookupPtr.getPointer() && "context already has a decls map");
assert(getPrimaryContext() == this &&
"creating decls map on non-primary context");
@@ -1328,7 +1387,7 @@
M = new StoredDeclsMap();
M->Previous = C.LastSDM;
C.LastSDM = llvm::PointerIntPair<StoredDeclsMap*,1>(M, Dependent);
- LookupPtr = M;
+ LookupPtr.setPointer(M);
return M;
}
@@ -1360,11 +1419,11 @@
assert(Parent->isDependentContext()
&& "cannot iterate dependent diagnostics of non-dependent context");
Parent = Parent->getPrimaryContext();
- if (!Parent->LookupPtr)
+ if (!Parent->LookupPtr.getPointer())
Parent->CreateStoredDeclsMap(C);
DependentStoredDeclsMap *Map
- = static_cast<DependentStoredDeclsMap*>(Parent->LookupPtr);
+ = static_cast<DependentStoredDeclsMap*>(Parent->LookupPtr.getPointer());
// Allocate the copy of the PartialDiagnostic via the ASTContext's
// BumpPtrAllocator, rather than the ASTContext itself.
Modified: cfe/branches/tooling/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/DeclCXX.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/DeclCXX.cpp (original)
+++ cfe/branches/tooling/lib/AST/DeclCXX.cpp Mon Mar 19 14:02:20 2012
@@ -636,7 +636,7 @@
// C++0x [dcl.init.aggr]p1:
// An aggregate is an array or a class with no user-provided
// constructors [...].
- if (!getASTContext().getLangOptions().CPlusPlus0x || UserProvided)
+ if (!getASTContext().getLangOpts().CPlusPlus0x || UserProvided)
data().Aggregate = false;
// C++ [class]p4:
@@ -798,7 +798,7 @@
ASTContext &Context = getASTContext();
QualType T = Context.getBaseElementType(Field->getType());
if (T->isObjCRetainableType() || T.isObjCGCStrong()) {
- if (!Context.getLangOptions().ObjCAutoRefCount ||
+ if (!Context.getLangOpts().ObjCAutoRefCount ||
T.getObjCLifetime() != Qualifiers::OCL_ExplicitNone)
setHasObjectMember(true);
} else if (!T.isPODType(Context))
@@ -1243,7 +1243,7 @@
void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
RecordDecl::completeDefinition();
- if (hasObjectMember() && getASTContext().getLangOptions().ObjCAutoRefCount) {
+ if (hasObjectMember() && getASTContext().getLangOpts().ObjCAutoRefCount) {
// Objective-C Automatic Reference Counting:
// If a class has a non-static data member of Objective-C pointer
// type (or array thereof), it is a non-POD type and its
@@ -1421,19 +1421,23 @@
assert(MD->isCanonicalDecl() && "Method is not canonical!");
assert(!MD->getParent()->isDependentContext() &&
"Can't add an overridden method to a class template!");
+ assert(MD->isVirtual() && "Method is not virtual!");
getASTContext().addOverriddenMethod(this, MD);
}
CXXMethodDecl::method_iterator CXXMethodDecl::begin_overridden_methods() const {
+ if (isa<CXXConstructorDecl>(this)) return 0;
return getASTContext().overridden_methods_begin(this);
}
CXXMethodDecl::method_iterator CXXMethodDecl::end_overridden_methods() const {
+ if (isa<CXXConstructorDecl>(this)) return 0;
return getASTContext().overridden_methods_end(this);
}
unsigned CXXMethodDecl::size_overridden_methods() const {
+ if (isa<CXXConstructorDecl>(this)) return 0;
return getASTContext().overridden_methods_size(this);
}
@@ -1712,8 +1716,8 @@
const CXXConstructorDecl *CXXConstructorDecl::getInheritedConstructor() const {
// Hack: we store the inherited constructor in the overridden method table
- method_iterator It = begin_overridden_methods();
- if (It == end_overridden_methods())
+ method_iterator It = getASTContext().overridden_methods_begin(this);
+ if (It == getASTContext().overridden_methods_end(this))
return 0;
return cast<CXXConstructorDecl>(*It);
@@ -1722,8 +1726,9 @@
void
CXXConstructorDecl::setInheritedConstructor(const CXXConstructorDecl *BaseCtor){
// Hack: we store the inherited constructor in the overridden method table
- assert(size_overridden_methods() == 0 && "Base ctor already set.");
- addOverriddenMethod(BaseCtor);
+ assert(getASTContext().overridden_methods_size(this) == 0 &&
+ "Base ctor already set.");
+ getASTContext().addOverriddenMethod(this, BaseCtor);
}
void CXXDestructorDecl::anchor() { }
Modified: cfe/branches/tooling/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/DeclObjC.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/DeclObjC.cpp (original)
+++ cfe/branches/tooling/lib/AST/DeclObjC.cpp Mon Mar 19 14:02:20 2012
@@ -334,10 +334,9 @@
return MethodDecl;
// Didn't find one yet - look through protocols.
- const ObjCList<ObjCProtocolDecl> &Protocols =
- ClassDecl->getReferencedProtocols();
- for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
- E = Protocols.end(); I != E; ++I)
+ for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
+ E = ClassDecl->protocol_end();
+ I != E; ++I)
if ((MethodDecl = (*I)->lookupMethod(Sel, isInstance)))
return MethodDecl;
if (!noCategoryLookup) {
@@ -628,7 +627,7 @@
bool selfIsPseudoStrong = false;
bool selfIsConsumed = false;
- if (Context.getLangOptions().ObjCAutoRefCount) {
+ if (Context.getLangOpts().ObjCAutoRefCount) {
if (isInstanceMethod()) {
selfIsConsumed = hasAttr<NSConsumesSelfAttr>();
@@ -850,11 +849,8 @@
ObjCInterfaceDecl *IDecl = this;
// 1st, look up the class.
- const ObjCList<ObjCProtocolDecl> &Protocols =
- IDecl->getReferencedProtocols();
-
- for (ObjCList<ObjCProtocolDecl>::iterator PI = Protocols.begin(),
- E = Protocols.end(); PI != E; ++PI) {
+ for (ObjCInterfaceDecl::protocol_iterator
+ PI = IDecl->protocol_begin(), E = IDecl->protocol_end(); PI != E; ++PI){
if (getASTContext().ProtocolCompatibleWithProtocol(lProto, *PI))
return true;
// This is dubious and is added to be compatible with gcc. In gcc, it is
Modified: cfe/branches/tooling/lib/AST/DeclTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/DeclTemplate.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/DeclTemplate.cpp (original)
+++ cfe/branches/tooling/lib/AST/DeclTemplate.cpp Mon Mar 19 14:02:20 2012
@@ -173,7 +173,7 @@
Arg = TemplateArgument(ArgType);
} else if (NonTypeTemplateParmDecl *NTTP =
dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
- Expr *E = new (Context) DeclRefExpr(NTTP,
+ Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
NTTP->getType().getNonLValueExprType(Context),
Expr::getValueKindForType(NTTP->getType()),
NTTP->getLocation());
Modified: cfe/branches/tooling/lib/AST/DeclarationName.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/DeclarationName.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/DeclarationName.cpp (original)
+++ cfe/branches/tooling/lib/AST/DeclarationName.cpp Mon Mar 19 14:02:20 2012
@@ -53,7 +53,7 @@
void *FETokenInfo;
};
-/// CXXLiberalOperatorName - Contains the actual identifier that makes up the
+/// CXXLiteralOperatorName - Contains the actual identifier that makes up the
/// name.
///
/// This identifier is stored here rather than directly in DeclarationName so as
@@ -64,6 +64,10 @@
public:
IdentifierInfo *ID;
+ /// FETokenInfo - Extra information associated with this operator
+ /// name that can be used by the front end.
+ void *FETokenInfo;
+
void Profile(llvm::FoldingSetNodeID &FSID) {
FSID.AddPointer(ID);
}
@@ -333,7 +337,7 @@
return getAsCXXOperatorIdName()->FETokenInfo;
case CXXLiteralOperatorName:
- return getCXXLiteralIdentifier()->getFETokenInfo<void>();
+ return getAsCXXLiteralOperatorIdName()->FETokenInfo;
default:
llvm_unreachable("Declaration name has no FETokenInfo");
@@ -357,7 +361,7 @@
break;
case CXXLiteralOperatorName:
- getCXXLiteralIdentifier()->setFETokenInfo(T);
+ getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
break;
default:
@@ -471,6 +475,7 @@
CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
LiteralName->ID = II;
+ LiteralName->FETokenInfo = 0;
LiteralNames->InsertNode(LiteralName, InsertPos);
return DeclarationName(LiteralName);
Modified: cfe/branches/tooling/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/Expr.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/Expr.cpp (original)
+++ cfe/branches/tooling/lib/AST/Expr.cpp Mon Mar 19 14:02:20 2012
@@ -94,6 +94,8 @@
// Amusing macro metaprogramming hack: check whether a class provides
// a more specific implementation of getExprLoc().
+//
+// See also Stmt.cpp:{getLocStart(),getLocEnd()}.
namespace {
/// This implementation is used when a class provides a custom
/// implementation of getExprLoc.
@@ -110,7 +112,7 @@
template <class E>
SourceLocation getExprLocImpl(const Expr *expr,
SourceLocation (Expr::*v)() const) {
- return static_cast<const E*>(expr)->getSourceRange().getBegin();
+ return static_cast<const E*>(expr)->getLocStart();
}
}
@@ -134,7 +136,7 @@
/// \brief Compute the type-, value-, and instantiation-dependence of a
/// declaration reference
/// based on the declaration being referenced.
-static void computeDeclRefDependence(NamedDecl *D, QualType T,
+static void computeDeclRefDependence(ASTContext &Ctx, NamedDecl *D, QualType T,
bool &TypeDependent,
bool &ValueDependent,
bool &InstantiationDependent) {
@@ -191,7 +193,7 @@
// - an entity with reference type and is initialized with an
// expression that is value-dependent [C++11]
if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
- if ((D->getASTContext().getLangOptions().CPlusPlus0x ?
+ if ((Ctx.getLangOpts().CPlusPlus0x ?
Var->getType()->isLiteralType() :
Var->getType()->isIntegralOrEnumerationType()) &&
(Var->getType().getCVRQualifiers() == Qualifiers::Const ||
@@ -224,12 +226,12 @@
}
}
-void DeclRefExpr::computeDependence() {
+void DeclRefExpr::computeDependence(ASTContext &Ctx) {
bool TypeDependent = false;
bool ValueDependent = false;
bool InstantiationDependent = false;
- computeDeclRefDependence(getDecl(), getType(), TypeDependent, ValueDependent,
- InstantiationDependent);
+ computeDeclRefDependence(Ctx, getDecl(), getType(), TypeDependent,
+ ValueDependent, InstantiationDependent);
// (TD) C++ [temp.dep.expr]p3:
// An id-expression is type-dependent if it contains:
@@ -258,9 +260,11 @@
ExprBits.ContainsUnexpandedParameterPack = true;
}
-DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
+DeclRefExpr::DeclRefExpr(ASTContext &Ctx,
+ NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
- ValueDecl *D, const DeclarationNameInfo &NameInfo,
+ ValueDecl *D, bool RefersToEnclosingLocal,
+ const DeclarationNameInfo &NameInfo,
NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs,
QualType T, ExprValueKind VK)
@@ -274,6 +278,7 @@
getInternalFoundDecl() = FoundD;
DeclRefExprBits.HasTemplateKWAndArgsInfo
= (TemplateArgs || TemplateKWLoc.isValid()) ? 1 : 0;
+ DeclRefExprBits.RefersToEnclosingLocal = RefersToEnclosingLocal;
if (TemplateArgs) {
bool Dependent = false;
bool InstantiationDependent = false;
@@ -289,19 +294,21 @@
}
DeclRefExprBits.HadMultipleCandidates = 0;
- computeDependence();
+ computeDependence(Ctx);
}
DeclRefExpr *DeclRefExpr::Create(ASTContext &Context,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
ValueDecl *D,
+ bool RefersToEnclosingLocal,
SourceLocation NameLoc,
QualType T,
ExprValueKind VK,
NamedDecl *FoundD,
const TemplateArgumentListInfo *TemplateArgs) {
return Create(Context, QualifierLoc, TemplateKWLoc, D,
+ RefersToEnclosingLocal,
DeclarationNameInfo(D->getDeclName(), NameLoc),
T, VK, FoundD, TemplateArgs);
}
@@ -310,6 +317,7 @@
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateKWLoc,
ValueDecl *D,
+ bool RefersToEnclosingLocal,
const DeclarationNameInfo &NameInfo,
QualType T,
ExprValueKind VK,
@@ -330,8 +338,9 @@
Size += ASTTemplateKWAndArgsInfo::sizeFor(0);
void *Mem = Context.Allocate(Size, llvm::alignOf<DeclRefExpr>());
- return new (Mem) DeclRefExpr(QualifierLoc, TemplateKWLoc, D, NameInfo,
- FoundD, TemplateArgs, T, VK);
+ return new (Mem) DeclRefExpr(Context, QualifierLoc, TemplateKWLoc, D,
+ RefersToEnclosingLocal,
+ NameInfo, FoundD, TemplateArgs, T, VK);
}
DeclRefExpr *DeclRefExpr::CreateEmpty(ASTContext &Context,
@@ -359,6 +368,16 @@
R.setEnd(getRAngleLoc());
return R;
}
+SourceLocation DeclRefExpr::getLocStart() const {
+ if (hasQualifier())
+ return getQualifierLoc().getBeginLoc();
+ return getNameInfo().getLocStart();
+}
+SourceLocation DeclRefExpr::getLocEnd() const {
+ if (hasExplicitTemplateArgs())
+ return getRAngleLoc();
+ return getNameInfo().getLocEnd();
+}
// FIXME: Maybe this should use DeclPrinter with a special "print predefined
// expr" policy instead.
@@ -379,7 +398,7 @@
Out << "static ";
}
- PrintingPolicy Policy(Context.getLangOptions());
+ PrintingPolicy Policy(Context.getLangOpts());
std::string Proto = FD->getQualifiedNameAsString(Policy);
@@ -892,6 +911,24 @@
end = getArg(getNumArgs() - 1)->getLocEnd();
return SourceRange(begin, end);
}
+SourceLocation CallExpr::getLocStart() const {
+ if (isa<CXXOperatorCallExpr>(this))
+ return cast<CXXOperatorCallExpr>(this)->getSourceRange().getBegin();
+
+ SourceLocation begin = getCallee()->getLocStart();
+ if (begin.isInvalid() && getNumArgs() > 0)
+ begin = getArg(0)->getLocStart();
+ return begin;
+}
+SourceLocation CallExpr::getLocEnd() const {
+ if (isa<CXXOperatorCallExpr>(this))
+ return cast<CXXOperatorCallExpr>(this)->getSourceRange().getEnd();
+
+ SourceLocation end = getRParenLoc();
+ if (end.isInvalid() && getNumArgs() > 0)
+ end = getArg(getNumArgs() - 1)->getLocEnd();
+ return end;
+}
OffsetOfExpr *OffsetOfExpr::Create(ASTContext &C, QualType type,
SourceLocation OperatorLoc,
@@ -1015,24 +1052,26 @@
}
SourceRange MemberExpr::getSourceRange() const {
- SourceLocation StartLoc;
+ return SourceRange(getLocStart(), getLocEnd());
+}
+SourceLocation MemberExpr::getLocStart() const {
if (isImplicitAccess()) {
if (hasQualifier())
- StartLoc = getQualifierLoc().getBeginLoc();
- else
- StartLoc = MemberLoc;
- } else {
- // FIXME: We don't want this to happen. Rather, we should be able to
- // detect all kinds of implicit accesses more cleanly.
- StartLoc = getBase()->getLocStart();
- if (StartLoc.isInvalid())
- StartLoc = MemberLoc;
+ return getQualifierLoc().getBeginLoc();
+ return MemberLoc;
}
- SourceLocation EndLoc = hasExplicitTemplateArgs()
- ? getRAngleLoc() : getMemberNameInfo().getEndLoc();
-
- return SourceRange(StartLoc, EndLoc);
+ // FIXME: We don't want this to happen. Rather, we should be able to
+ // detect all kinds of implicit accesses more cleanly.
+ SourceLocation BaseStartLoc = getBase()->getLocStart();
+ if (BaseStartLoc.isValid())
+ return BaseStartLoc;
+ return MemberLoc;
+}
+SourceLocation MemberExpr::getLocEnd() const {
+ if (hasExplicitTemplateArgs())
+ return getRAngleLoc();
+ return getMemberNameInfo().getEndLoc();
}
void CastExpr::CheckCastConsistency() const {
@@ -1711,7 +1750,7 @@
case ObjCMessageExprClass: {
const ObjCMessageExpr *ME = cast<ObjCMessageExpr>(this);
- if (Ctx.getLangOptions().ObjCAutoRefCount &&
+ if (Ctx.getLangOpts().ObjCAutoRefCount &&
ME->isInstanceMessage() &&
!ME->getType()->isVoidType() &&
ME->getSelector().getIdentifierInfoForSlot(0) &&
@@ -1834,14 +1873,8 @@
->isOBJCGCCandidate(Ctx);
case CStyleCastExprClass:
return cast<CStyleCastExpr>(E)->getSubExpr()->isOBJCGCCandidate(Ctx);
- case BlockDeclRefExprClass:
case DeclRefExprClass: {
-
- const Decl *D;
- if (const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E))
- D = BDRE->getDecl();
- else
- D = cast<DeclRefExpr>(E)->getDecl();
+ const Decl *D = cast<DeclRefExpr>(E)->getDecl();
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
if (VD->hasGlobalStorage())
@@ -2098,7 +2131,6 @@
// potentially throwing unless we decide to close off that
// possibility.
case ObjCArrayLiteralClass:
- case ObjCBoolLiteralExprClass:
case ObjCDictionaryLiteralClass:
case ObjCNumericLiteralClass:
return CT_Can;
@@ -2161,7 +2193,6 @@
case AsTypeExprClass:
case BinaryConditionalOperatorClass:
case BlockExprClass:
- case BlockDeclRefExprClass:
case CUDAKernelCallExprClass:
case DeclRefExprClass:
case ObjCBridgedCastExprClass:
@@ -2199,6 +2230,7 @@
case IntegerLiteralClass:
case ObjCEncodeExprClass:
case ObjCStringLiteralClass:
+ case ObjCBoolLiteralExprClass:
case OpaqueValueExprClass:
case PredefinedExprClass:
case SizeOfPackExprClass:
@@ -2748,7 +2780,7 @@
// Strip off a cast to void*, if it exists. Except in C++.
if (const ExplicitCastExpr *CE = dyn_cast<ExplicitCastExpr>(this)) {
- if (!Ctx.getLangOptions().CPlusPlus) {
+ if (!Ctx.getLangOpts().CPlusPlus) {
// Check that it is a cast to void*.
if (const PointerType *PT = CE->getType()->getAs<PointerType>()) {
QualType Pointee = PT->getPointeeType();
@@ -2796,14 +2828,14 @@
}
// This expression must be an integer type.
if (!getType()->isIntegerType() ||
- (Ctx.getLangOptions().CPlusPlus && getType()->isEnumeralType()))
+ (Ctx.getLangOpts().CPlusPlus && getType()->isEnumeralType()))
return NPCK_NotNull;
// If we have an integer constant expression, we need to *evaluate* it and
// test for the value 0. Don't use the C++11 constant expression semantics
// for this, for now; once the dust settles on core issue 903, we might only
// allow a literal 0 here in C++11 mode.
- if (Ctx.getLangOptions().CPlusPlus0x) {
+ if (Ctx.getLangOpts().CPlusPlus0x) {
if (!isCXX98IntegralConstantExpr(Ctx))
return NPCK_NotNull;
} else {
@@ -3631,24 +3663,6 @@
reinterpret_cast<Stmt **>(getArgs() + getNumArgs()));
}
-// Blocks
-BlockDeclRefExpr::BlockDeclRefExpr(VarDecl *d, QualType t, ExprValueKind VK,
- SourceLocation l, bool ByRef,
- bool constAdded)
- : Expr(BlockDeclRefExprClass, t, VK, OK_Ordinary, false, false, false,
- d->isParameterPack()),
- D(d), Loc(l), IsByRef(ByRef), ConstQualAdded(constAdded)
-{
- bool TypeDependent = false;
- bool ValueDependent = false;
- bool InstantiationDependent = false;
- computeDeclRefDependence(D, getType(), TypeDependent, ValueDependent,
- InstantiationDependent);
- ExprBits.TypeDependent = TypeDependent;
- ExprBits.ValueDependent = ValueDependent;
- ExprBits.InstantiationDependent = InstantiationDependent;
-}
-
ObjCArrayLiteral::ObjCArrayLiteral(llvm::ArrayRef<Expr *> Elements,
QualType T, ObjCMethodDecl *Method,
SourceRange SR)
Modified: cfe/branches/tooling/lib/AST/ExprClassification.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/ExprClassification.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/ExprClassification.cpp (original)
+++ cfe/branches/tooling/lib/AST/ExprClassification.cpp Mon Mar 19 14:02:20 2012
@@ -55,7 +55,7 @@
Cl::Kinds kind = ClassifyInternal(Ctx, this);
// C99 6.3.2.1: An lvalue is an expression with an object type or an
// incomplete type other than void.
- if (!Ctx.getLangOptions().CPlusPlus) {
+ if (!Ctx.getLangOpts().CPlusPlus) {
// Thus, no functions.
if (TR->isFunctionType() || TR == Ctx.OverloadTy)
kind = Cl::CL_Function;
@@ -89,7 +89,7 @@
static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) {
// This function takes the first stab at classifying expressions.
- const LangOptions &Lang = Ctx.getLangOptions();
+ const LangOptions &Lang = Ctx.getLangOpts();
switch (E->getStmtClass()) {
case Stmt::NoStmtClass:
@@ -126,7 +126,7 @@
// C99 6.5.2.5p5 says that compound literals are lvalues.
// In C++, they're class temporaries.
case Expr::CompoundLiteralExprClass:
- return Ctx.getLangOptions().CPlusPlus? Cl::CL_ClassTemporary
+ return Ctx.getLangOpts().CPlusPlus? Cl::CL_ClassTemporary
: Cl::CL_LValue;
// Expressions that are prvalues.
@@ -189,9 +189,6 @@
return isa<FunctionDecl>(cast<DeclRefExpr>(E)->getDecl())
? Cl::CL_PRValue : Cl::CL_LValue;
return ClassifyDecl(Ctx, cast<DeclRefExpr>(E)->getDecl());
- // We deal with names referenced from blocks the same way.
- case Expr::BlockDeclRefExprClass:
- return ClassifyDecl(Ctx, cast<BlockDeclRefExpr>(E)->getDecl());
// Member access is complex.
case Expr::MemberExprClass:
@@ -399,7 +396,7 @@
else
islvalue = isa<VarDecl>(D) || isa<FieldDecl>(D) ||
isa<IndirectFieldDecl>(D) ||
- (Ctx.getLangOptions().CPlusPlus &&
+ (Ctx.getLangOpts().CPlusPlus &&
(isa<FunctionDecl>(D) || isa<FunctionTemplateDecl>(D)));
return islvalue ? Cl::CL_LValue : Cl::CL_PRValue;
@@ -410,7 +407,7 @@
/// calls and casts.
static Cl::Kinds ClassifyUnnamed(ASTContext &Ctx, QualType T) {
// In C, function calls are always rvalues.
- if (!Ctx.getLangOptions().CPlusPlus) return Cl::CL_PRValue;
+ if (!Ctx.getLangOpts().CPlusPlus) return Cl::CL_PRValue;
// C++ [expr.call]p10: A function call is an lvalue if the result type is an
// lvalue reference type or an rvalue reference to function type, an xvalue
@@ -431,7 +428,7 @@
? Cl::CL_PRValue : Cl::CL_LValue);
// Handle C first, it's easier.
- if (!Ctx.getLangOptions().CPlusPlus) {
+ if (!Ctx.getLangOpts().CPlusPlus) {
// C99 6.5.2.3p3
// For dot access, the expression is an lvalue if the first part is. For
// arrow access, it always is an lvalue.
@@ -483,7 +480,7 @@
}
static Cl::Kinds ClassifyBinaryOp(ASTContext &Ctx, const BinaryOperator *E) {
- assert(Ctx.getLangOptions().CPlusPlus &&
+ assert(Ctx.getLangOpts().CPlusPlus &&
"This is only relevant for C++.");
// C++ [expr.ass]p1: All [...] return an lvalue referring to the left operand.
// Except we override this for writes to ObjC properties.
@@ -519,7 +516,7 @@
static Cl::Kinds ClassifyConditional(ASTContext &Ctx, const Expr *True,
const Expr *False) {
- assert(Ctx.getLangOptions().CPlusPlus &&
+ assert(Ctx.getLangOpts().CPlusPlus &&
"This is only relevant for C++.");
// C++ [expr.cond]p2
@@ -558,18 +555,9 @@
// This is the lvalue case.
// Functions are lvalues in C++, but not modifiable. (C++ [basic.lval]p6)
- if (Ctx.getLangOptions().CPlusPlus && E->getType()->isFunctionType())
+ if (Ctx.getLangOpts().CPlusPlus && E->getType()->isFunctionType())
return Cl::CM_Function;
- // You cannot assign to a variable outside a block from within the block if
- // it is not marked __block, e.g.
- // void takeclosure(void (^C)(void));
- // void func() { int x = 1; takeclosure(^{ x = 7; }); }
- if (const BlockDeclRefExpr *BDR = dyn_cast<BlockDeclRefExpr>(E)) {
- if (!BDR->isByRef() && isa<VarDecl>(BDR->getDecl()))
- return Cl::CM_NotBlockQualified;
- }
-
// Assignment to a property in ObjC is an implicit setter access. But a
// setter might not exist.
if (const ObjCPropertyRefExpr *Expr = dyn_cast<ObjCPropertyRefExpr>(E)) {
@@ -581,6 +569,7 @@
// Const stuff is obviously not modifiable.
if (CT.isConstQualified())
return Cl::CM_ConstQualified;
+
// Arrays are not modifiable, only their elements are.
if (CT->isArrayType())
return Cl::CM_ArrayType;
@@ -591,7 +580,7 @@
// Records with any const fields (recursively) are not modifiable.
if (const RecordType *R = CT->getAs<RecordType>()) {
assert((E->getObjectKind() == OK_ObjCProperty ||
- !Ctx.getLangOptions().CPlusPlus) &&
+ !Ctx.getLangOpts().CPlusPlus) &&
"C++ struct assignment should be resolved by the "
"copy assignment operator.");
if (R->hasConstFields())
@@ -646,7 +635,6 @@
case Cl::CM_Function: return MLV_NotObjectType;
case Cl::CM_LValueCast:
llvm_unreachable("CM_LValueCast and CL_LValue don't match");
- case Cl::CM_NotBlockQualified: return MLV_NotBlockQualified;
case Cl::CM_NoSetterProperty: return MLV_NoSetterProperty;
case Cl::CM_ConstQualified: return MLV_ConstQualified;
case Cl::CM_ArrayType: return MLV_ArrayType;
Modified: cfe/branches/tooling/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/ExprConstant.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/ExprConstant.cpp (original)
+++ cfe/branches/tooling/lib/AST/ExprConstant.cpp Mon Mar 19 14:02:20 2012
@@ -44,7 +44,6 @@
#include "clang/Basic/Builtins.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/SaveAndRestore.h"
#include <cstring>
#include <functional>
@@ -388,18 +387,12 @@
/// are suppressed.
bool CheckingPotentialConstantExpression;
- /// \brief Stack depth of IntExprEvaluator.
- /// We check this against a maximum value to avoid stack overflow, see
- /// test case in test/Sema/many-logical-ops.c.
- // FIXME: This is a hack; handle properly unlimited logical ops.
- unsigned IntExprEvaluatorDepth;
-
EvalInfo(const ASTContext &C, Expr::EvalStatus &S)
: Ctx(const_cast<ASTContext&>(C)), EvalStatus(S), CurrentCall(0),
CallStackDepth(0), NextCallIndex(1),
BottomFrame(*this, SourceLocation(), 0, 0, 0),
EvaluatingDecl(0), EvaluatingDeclValue(0), HasActiveDiagnostic(false),
- CheckingPotentialConstantExpression(false), IntExprEvaluatorDepth(0) {}
+ CheckingPotentialConstantExpression(false) {}
const APValue *getOpaqueValue(const OpaqueValueExpr *e) const {
MapTy::const_iterator i = OpaqueValues.find(e);
@@ -412,7 +405,7 @@
EvaluatingDeclValue = &Value;
}
- const LangOptions &getLangOpts() const { return Ctx.getLangOptions(); }
+ const LangOptions &getLangOpts() const { return Ctx.getLangOpts(); }
bool CheckCallLimit(SourceLocation Loc) {
// Don't perform any constexpr calls (other than the call we're checking)
@@ -480,9 +473,19 @@
return OptionalDiagnostic();
}
+ OptionalDiagnostic Diag(const Expr *E, diag::kind DiagId
+ = diag::note_invalid_subexpr_in_const_expr,
+ unsigned ExtraNotes = 0) {
+ if (EvalStatus.Diag)
+ return Diag(E->getExprLoc(), DiagId, ExtraNotes);
+ HasActiveDiagnostic = false;
+ return OptionalDiagnostic();
+ }
+
/// Diagnose that the evaluation does not produce a C++11 core constant
/// expression.
- OptionalDiagnostic CCEDiag(SourceLocation Loc, diag::kind DiagId
+ template<typename LocArg>
+ OptionalDiagnostic CCEDiag(LocArg Loc, diag::kind DiagId
= diag::note_invalid_subexpr_in_const_expr,
unsigned ExtraNotes = 0) {
// Don't override a previous diagnostic.
@@ -556,7 +559,7 @@
if (Invalid)
return false;
if (isOnePastTheEnd()) {
- Info.CCEDiag(E->getExprLoc(), diag::note_constexpr_past_end_subobject)
+ Info.CCEDiag(E, diag::note_constexpr_past_end_subobject)
<< CSK;
setInvalid();
return false;
@@ -567,11 +570,11 @@
void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E, uint64_t N) {
if (MostDerivedPathLength == Entries.size() && MostDerivedArraySize)
- Info.CCEDiag(E->getExprLoc(), diag::note_constexpr_array_index)
+ Info.CCEDiag(E, diag::note_constexpr_array_index)
<< static_cast<int>(N) << /*array*/ 0
<< static_cast<unsigned>(MostDerivedArraySize);
else
- Info.CCEDiag(E->getExprLoc(), diag::note_constexpr_array_index)
+ Info.CCEDiag(E, diag::note_constexpr_array_index)
<< static_cast<int>(N) << /*non-array*/ 1;
setInvalid();
}
@@ -730,7 +733,7 @@
if (Designator.Invalid)
return false;
if (!Base) {
- Info.CCEDiag(E->getExprLoc(), diag::note_constexpr_null_subobject)
+ Info.CCEDiag(E, diag::note_constexpr_null_subobject)
<< CSK;
Designator.setInvalid();
return false;
@@ -741,27 +744,30 @@
// Check this LValue refers to an object. If not, set the designator to be
// invalid and emit a diagnostic.
bool checkSubobject(EvalInfo &Info, const Expr *E, CheckSubobjectKind CSK) {
+ // Outside C++11, do not build a designator referring to a subobject of
+ // any object: we won't use such a designator for anything.
+ if (!Info.getLangOpts().CPlusPlus0x)
+ Designator.setInvalid();
return checkNullPointer(Info, E, CSK) &&
Designator.checkSubobject(Info, E, CSK);
}
void addDecl(EvalInfo &Info, const Expr *E,
const Decl *D, bool Virtual = false) {
- checkSubobject(Info, E, isa<FieldDecl>(D) ? CSK_Field : CSK_Base);
- Designator.addDeclUnchecked(D, Virtual);
+ if (checkSubobject(Info, E, isa<FieldDecl>(D) ? CSK_Field : CSK_Base))
+ Designator.addDeclUnchecked(D, Virtual);
}
void addArray(EvalInfo &Info, const Expr *E, const ConstantArrayType *CAT) {
- checkSubobject(Info, E, CSK_ArrayToPointer);
- Designator.addArrayUnchecked(CAT);
+ if (checkSubobject(Info, E, CSK_ArrayToPointer))
+ Designator.addArrayUnchecked(CAT);
}
void addComplex(EvalInfo &Info, const Expr *E, QualType EltTy, bool Imag) {
- checkSubobject(Info, E, Imag ? CSK_Imag : CSK_Real);
- Designator.addComplexUnchecked(EltTy, Imag);
+ if (checkSubobject(Info, E, Imag ? CSK_Imag : CSK_Real))
+ Designator.addComplexUnchecked(EltTy, Imag);
}
void adjustIndex(EvalInfo &Info, const Expr *E, uint64_t N) {
- if (!checkNullPointer(Info, E, CSK_ArrayIndex))
- return;
- Designator.adjustIndex(Info, E, N);
+ if (checkNullPointer(Info, E, CSK_ArrayIndex))
+ Designator.adjustIndex(Info, E, N);
}
};
@@ -1020,10 +1026,10 @@
// Prvalue constant expressions must be of literal types.
if (Info.getLangOpts().CPlusPlus0x)
- Info.Diag(E->getExprLoc(), diag::note_constexpr_nonliteral)
+ Info.Diag(E, diag::note_constexpr_nonliteral)
<< E->getType();
else
- Info.Diag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr);
+ Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
return false;
}
@@ -1155,7 +1161,7 @@
template<typename T>
static bool HandleOverflow(EvalInfo &Info, const Expr *E,
const T &SrcValue, QualType DestType) {
- Info.Diag(E->getExprLoc(), diag::note_constexpr_overflow)
+ Info.Diag(E, diag::note_constexpr_overflow)
<< SrcValue << DestType;
return false;
}
@@ -1240,7 +1246,7 @@
} else {
// Don't try to handle vectors of anything other than int or float
// (not sure if it's possible to hit this case).
- Info.Diag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr);
+ Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
return false;
}
unsigned BaseEltSize = EltAsInt.getBitWidth();
@@ -1253,7 +1259,7 @@
}
// Give up if the input isn't an int, float, or vector. For example, we
// reject "(v4i16)(intptr_t)&a".
- Info.Diag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr);
+ Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
return false;
}
@@ -1414,7 +1420,7 @@
if (Info.CheckingPotentialConstantExpression)
return false;
if (!Frame || !Frame->Arguments) {
- Info.Diag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr);
+ Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
return false;
}
Result = Frame->Arguments[PVD->getFunctionScopeIndex()];
@@ -1427,7 +1433,7 @@
// If we're checking a potential constant expression, the variable could be
// initialized later.
if (!Info.CheckingPotentialConstantExpression)
- Info.Diag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr);
+ Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
return false;
}
@@ -1441,7 +1447,7 @@
// Never evaluate the initializer of a weak variable. We can't be sure that
// this is the definition which will be used.
if (VD->isWeak()) {
- Info.Diag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr);
+ Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
return false;
}
@@ -1449,13 +1455,13 @@
// this in the cases where it matters for conformance.
llvm::SmallVector<PartialDiagnosticAt, 8> Notes;
if (!VD->evaluateValue(Notes)) {
- Info.Diag(E->getExprLoc(), diag::note_constexpr_var_init_non_constant,
+ Info.Diag(E, diag::note_constexpr_var_init_non_constant,
Notes.size() + 1) << VD;
Info.Note(VD->getLocation(), diag::note_declared_at);
Info.addNotes(Notes);
return false;
} else if (!VD->checkInitIsICE()) {
- Info.CCEDiag(E->getExprLoc(), diag::note_constexpr_var_init_non_constant,
+ Info.CCEDiag(E, diag::note_constexpr_var_init_non_constant,
Notes.size() + 1) << VD;
Info.Note(VD->getLocation(), diag::note_declared_at);
Info.addNotes(Notes);
@@ -1507,7 +1513,7 @@
// A diagnostic will have already been produced.
return false;
if (Sub.isOnePastTheEnd()) {
- Info.Diag(E->getExprLoc(), Info.getLangOpts().CPlusPlus0x ?
+ Info.Diag(E, Info.getLangOpts().CPlusPlus0x ?
(unsigned)diag::note_constexpr_read_past_end :
(unsigned)diag::note_invalid_subexpr_in_const_expr);
return false;
@@ -1518,7 +1524,7 @@
// This object might be initialized later.
return false;
- const APValue *O = &Obj;
+ APValue *O = &Obj;
// Walk the designator's path to find the subobject.
for (unsigned I = 0, N = Sub.Entries.size(); I != N; ++I) {
if (ObjType->isArrayType()) {
@@ -1529,7 +1535,7 @@
if (CAT->getSize().ule(Index)) {
// Note, it should not be possible to form a pointer with a valid
// designator which points more than one past the end of the array.
- Info.Diag(E->getExprLoc(), Info.getLangOpts().CPlusPlus0x ?
+ Info.Diag(E, Info.getLangOpts().CPlusPlus0x ?
(unsigned)diag::note_constexpr_read_past_end :
(unsigned)diag::note_invalid_subexpr_in_const_expr);
return false;
@@ -1551,7 +1557,7 @@
// Next subobject is a complex number.
uint64_t Index = Sub.Entries[I].ArrayIndex;
if (Index > 1) {
- Info.Diag(E->getExprLoc(), Info.getLangOpts().CPlusPlus0x ?
+ Info.Diag(E, Info.getLangOpts().CPlusPlus0x ?
(unsigned)diag::note_constexpr_read_past_end :
(unsigned)diag::note_invalid_subexpr_in_const_expr);
return false;
@@ -1568,7 +1574,7 @@
return true;
} else if (const FieldDecl *Field = getAsField(Sub.Entries[I])) {
if (Field->isMutable()) {
- Info.Diag(E->getExprLoc(), diag::note_constexpr_ltor_mutable, 1)
+ Info.Diag(E, diag::note_constexpr_ltor_mutable, 1)
<< Field;
Info.Note(Field->getLocation(), diag::note_declared_at);
return false;
@@ -1580,8 +1586,7 @@
const FieldDecl *UnionField = O->getUnionField();
if (!UnionField ||
UnionField->getCanonicalDecl() != Field->getCanonicalDecl()) {
- Info.Diag(E->getExprLoc(),
- diag::note_constexpr_read_inactive_union_member)
+ Info.Diag(E, diag::note_constexpr_read_inactive_union_member)
<< Field << !UnionField << UnionField;
return false;
}
@@ -1593,11 +1598,11 @@
if (ObjType.isVolatileQualified()) {
if (Info.getLangOpts().CPlusPlus) {
// FIXME: Include a description of the path to the volatile subobject.
- Info.Diag(E->getExprLoc(), diag::note_constexpr_ltor_volatile_obj, 1)
+ Info.Diag(E, diag::note_constexpr_ltor_volatile_obj, 1)
<< 2 << Field;
Info.Note(Field->getLocation(), diag::note_declared_at);
} else {
- Info.Diag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr);
+ Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
}
return false;
}
@@ -1611,12 +1616,18 @@
if (O->isUninit()) {
if (!Info.CheckingPotentialConstantExpression)
- Info.Diag(E->getExprLoc(), diag::note_constexpr_read_uninit);
+ Info.Diag(E, diag::note_constexpr_read_uninit);
return false;
}
}
- Obj = APValue(*O);
+ // This may look super-stupid, but it serves an important purpose: if we just
+ // swapped Obj and *O, we'd create an object which had itself as a subobject.
+ // To avoid the leak, we ensure that Tmp ends up owning the original complete
+ // object, which is destroyed by Tmp's destructor.
+ APValue Tmp;
+ O->swap(Tmp);
+ Obj.swap(Tmp);
return true;
}
@@ -1696,11 +1707,10 @@
return false;
const Expr *Base = LVal.Base.dyn_cast<const Expr*>();
- SourceLocation Loc = Conv->getExprLoc();
if (!LVal.Base) {
// FIXME: Indirection through a null pointer deserves a specific diagnostic.
- Info.Diag(Loc, diag::note_invalid_subexpr_in_const_expr);
+ Info.Diag(Conv, diag::note_invalid_subexpr_in_const_expr);
return false;
}
@@ -1708,7 +1718,7 @@
if (LVal.CallIndex) {
Frame = Info.getCallFrame(LVal.CallIndex);
if (!Frame) {
- Info.Diag(Loc, diag::note_constexpr_lifetime_ended, 1) << !Base;
+ Info.Diag(Conv, diag::note_constexpr_lifetime_ended, 1) << !Base;
NoteLValueLocation(Info, LVal.Base);
return false;
}
@@ -1720,9 +1730,9 @@
// semantics.
if (Type.isVolatileQualified()) {
if (Info.getLangOpts().CPlusPlus)
- Info.Diag(Loc, diag::note_constexpr_ltor_volatile_type) << Type;
+ Info.Diag(Conv, diag::note_constexpr_ltor_volatile_type) << Type;
else
- Info.Diag(Loc);
+ Info.Diag(Conv);
return false;
}
@@ -1733,10 +1743,10 @@
// parameters are constant expressions even if they're non-const.
// In C, such things can also be folded, although they are not ICEs.
const VarDecl *VD = dyn_cast<VarDecl>(D);
- if (const VarDecl *VDef = VD->getDefinition())
+ if (const VarDecl *VDef = VD->getDefinition(Info.Ctx))
VD = VDef;
if (!VD || VD->isInvalidDecl()) {
- Info.Diag(Loc);
+ Info.Diag(Conv);
return false;
}
@@ -1745,10 +1755,10 @@
QualType VT = VD->getType();
if (VT.isVolatileQualified()) {
if (Info.getLangOpts().CPlusPlus) {
- Info.Diag(Loc, diag::note_constexpr_ltor_volatile_obj, 1) << 1 << VD;
+ Info.Diag(Conv, diag::note_constexpr_ltor_volatile_obj, 1) << 1 << VD;
Info.Note(VD->getLocation(), diag::note_declared_at);
} else {
- Info.Diag(Loc);
+ Info.Diag(Conv);
}
return false;
}
@@ -1759,10 +1769,10 @@
} else if (VT->isIntegralOrEnumerationType()) {
if (!VT.isConstQualified()) {
if (Info.getLangOpts().CPlusPlus) {
- Info.Diag(Loc, diag::note_constexpr_ltor_non_const_int, 1) << VD;
+ Info.Diag(Conv, diag::note_constexpr_ltor_non_const_int, 1) << VD;
Info.Note(VD->getLocation(), diag::note_declared_at);
} else {
- Info.Diag(Loc);
+ Info.Diag(Conv);
}
return false;
}
@@ -1771,18 +1781,18 @@
// static const data members of such types (supported as an extension)
// more useful.
if (Info.getLangOpts().CPlusPlus0x) {
- Info.CCEDiag(Loc, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
+ Info.CCEDiag(Conv, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
Info.Note(VD->getLocation(), diag::note_declared_at);
} else {
- Info.CCEDiag(Loc);
+ Info.CCEDiag(Conv);
}
} else {
// FIXME: Allow folding of values of any literal type in all languages.
if (Info.getLangOpts().CPlusPlus0x) {
- Info.Diag(Loc, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
+ Info.Diag(Conv, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
Info.Note(VD->getLocation(), diag::note_declared_at);
} else {
- Info.Diag(Loc);
+ Info.Diag(Conv);
}
return false;
}
@@ -1806,7 +1816,7 @@
if (unsigned CallIndex = RVal.getLValueCallIndex()) {
Frame = Info.getCallFrame(CallIndex);
if (!Frame) {
- Info.Diag(Loc, diag::note_constexpr_lifetime_ended, 1) << !Base;
+ Info.Diag(Conv, diag::note_constexpr_lifetime_ended, 1) << !Base;
NoteLValueLocation(Info, RVal.getLValueBase());
return false;
}
@@ -1818,10 +1828,10 @@
// Volatile temporary objects cannot be read in constant expressions.
if (Base->getType().isVolatileQualified()) {
if (Info.getLangOpts().CPlusPlus) {
- Info.Diag(Loc, diag::note_constexpr_ltor_volatile_obj, 1) << 0;
+ Info.Diag(Conv, diag::note_constexpr_ltor_volatile_obj, 1) << 0;
Info.Note(Base->getExprLoc(), diag::note_constexpr_temporary_here);
} else {
- Info.Diag(Loc);
+ Info.Diag(Conv);
}
return false;
}
@@ -1844,7 +1854,7 @@
// FIXME: Support PredefinedExpr, ObjCEncodeExpr, MakeStringConstant
RVal = APValue(Base, CharUnits::Zero(), APValue::NoLValuePath(), 0);
} else {
- Info.Diag(Conv->getExprLoc(), diag::note_invalid_subexpr_in_const_expr);
+ Info.Diag(Conv, diag::note_invalid_subexpr_in_const_expr);
return false;
}
@@ -1970,7 +1980,7 @@
// Check this cast lands within the final derived-to-base subobject path.
if (D.MostDerivedPathLength + E->path_size() > D.Entries.size()) {
- Info.CCEDiag(E->getExprLoc(), diag::note_constexpr_invalid_downcast)
+ Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
<< D.MostDerivedType << TargetQT;
return false;
}
@@ -1985,7 +1995,7 @@
else
FinalType = getAsBaseClass(D.Entries[NewEntriesSize - 1]);
if (FinalType->getCanonicalDecl() != TargetType->getCanonicalDecl()) {
- Info.CCEDiag(E->getExprLoc(), diag::note_constexpr_invalid_downcast)
+ Info.CCEDiag(E, diag::note_constexpr_invalid_downcast)
<< D.MostDerivedType << TargetQT;
return false;
}
@@ -2278,11 +2288,6 @@
return true;
return false;
}
- bool VisitBlockDeclRefExpr (const BlockDeclRefExpr *E) {
- if (Ctx.getCanonicalType(E->getType()).isVolatileQualified())
- return true;
- return false;
- }
// We don't want to evaluate BlockExprs multiple times, as they generate
// a ton of code.
@@ -2419,24 +2424,26 @@
typedef ExprEvaluatorBase ExprEvaluatorBaseTy;
OptionalDiagnostic CCEDiag(const Expr *E, diag::kind D) {
- return Info.CCEDiag(E->getExprLoc(), D);
+ return Info.CCEDiag(E, D);
}
+ RetTy ZeroInitialization(const Expr *E) { return Error(E); }
+
+public:
+ ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
+
+ EvalInfo &getEvalInfo() { return Info; }
+
/// Report an evaluation error. This should only be called when an error is
/// first discovered. When propagating an error, just return false.
bool Error(const Expr *E, diag::kind D) {
- Info.Diag(E->getExprLoc(), D);
+ Info.Diag(E, D);
return false;
}
bool Error(const Expr *E) {
return Error(E, diag::note_invalid_subexpr_in_const_expr);
}
- RetTy ZeroInitialization(const Expr *E) { return Error(E); }
-
-public:
- ExprEvaluatorBase(EvalInfo &Info) : Info(Info) {}
-
RetTy VisitStmt(const Stmt *) {
llvm_unreachable("Expression evaluator should not be called on stmts");
}
@@ -2956,7 +2963,7 @@
return Success(E);
CXXRecordDecl *RD = E->getExprOperand()->getType()->getAsCXXRecordDecl();
if (RD && RD->isPolymorphic()) {
- Info.Diag(E->getExprLoc(), diag::note_constexpr_typeid_polymorphic)
+ Info.Diag(E, diag::note_constexpr_typeid_polymorphic)
<< E->getExprOperand()->getType()
<< E->getExprOperand()->getSourceRange();
return false;
@@ -3404,7 +3411,7 @@
}
if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) {
- Info.Diag(E->getExprLoc(), diag::note_constexpr_virtual_base) << RD;
+ Info.Diag(E, diag::note_constexpr_virtual_base) << RD;
return false;
}
@@ -3742,7 +3749,7 @@
llvm::APSInt sInt(32);
if (CountInits < NumInits) {
if (!EvaluateInteger(E->getInit(CountInits), sInt, Info))
- return Error(E);
+ return false;
} else // trailing integer zero.
sInt = Info.Ctx.MakeIntValue(0, EltTy);
Elements.push_back(APValue(sInt));
@@ -3751,7 +3758,7 @@
llvm::APFloat f(0.0);
if (CountInits < NumInits) {
if (!EvaluateFloat(E->getInit(CountInits), f, Info))
- return Error(E);
+ return false;
} else // trailing float zero.
f = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(EltTy));
Elements.push_back(APValue(f));
@@ -3953,7 +3960,7 @@
IntExprEvaluator(EvalInfo &info, APValue &result)
: ExprEvaluatorBaseTy(info), Result(result) {}
- bool Success(const llvm::APSInt &SI, const Expr *E) {
+ bool Success(const llvm::APSInt &SI, const Expr *E, APValue &Result) {
assert(E->getType()->isIntegralOrEnumerationType() &&
"Invalid evaluation result.");
assert(SI.isSigned() == E->getType()->isSignedIntegerOrEnumerationType() &&
@@ -3963,8 +3970,11 @@
Result = APValue(SI);
return true;
}
+ bool Success(const llvm::APSInt &SI, const Expr *E) {
+ return Success(SI, E, Result);
+ }
- bool Success(const llvm::APInt &I, const Expr *E) {
+ bool Success(const llvm::APInt &I, const Expr *E, APValue &Result) {
assert(E->getType()->isIntegralOrEnumerationType() &&
"Invalid evaluation result.");
assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) &&
@@ -3974,13 +3984,19 @@
E->getType()->isUnsignedIntegerOrEnumerationType());
return true;
}
+ bool Success(const llvm::APInt &I, const Expr *E) {
+ return Success(I, E, Result);
+ }
- bool Success(uint64_t Value, const Expr *E) {
+ bool Success(uint64_t Value, const Expr *E, APValue &Result) {
assert(E->getType()->isIntegralOrEnumerationType() &&
"Invalid evaluation result.");
Result = APValue(Info.Ctx.MakeIntValue(Value, E->getType()));
return true;
}
+ bool Success(uint64_t Value, const Expr *E) {
+ return Success(Value, E, Result);
+ }
bool Success(CharUnits Size, const Expr *E) {
return Success(Size.getQuantity(), E);
@@ -3996,20 +4012,6 @@
bool ZeroInitialization(const Expr *E) { return Success(0, E); }
- // FIXME: See EvalInfo::IntExprEvaluatorDepth.
- bool Visit(const Expr *E) {
- SaveAndRestore<unsigned> Depth(Info.IntExprEvaluatorDepth,
- Info.IntExprEvaluatorDepth+1);
- const unsigned MaxDepth = 512;
- if (Depth.get() > MaxDepth) {
- Info.Ctx.getDiagnostics().Report(E->getExprLoc(),
- diag::err_intexpr_depth_limit_exceeded);
- return false;
- }
-
- return ExprEvaluatorBaseTy::Visit(E);
- }
-
//===--------------------------------------------------------------------===//
// Visitor Methods
//===--------------------------------------------------------------------===//
@@ -4114,7 +4116,7 @@
if (!Val.isInt()) {
// FIXME: It would be better to produce the diagnostic for casting
// a pointer to an integer.
- Info.Diag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr);
+ Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
return false;
}
Result = Val.getInt();
@@ -4210,7 +4212,7 @@
/// character of a string literal.
template<typename LValue>
static bool EvaluateBuiltinConstantPForLValue(const LValue &LV) {
- const Expr *E = LV.getLValueBase().dyn_cast<const Expr*>();
+ const Expr *E = LV.getLValueBase().template dyn_cast<const Expr*>();
return E && isa<StringLiteral>(E) && LV.getLValueOffset().isZero();
}
@@ -4337,10 +4339,10 @@
case Builtin::BIstrlen:
// A call to strlen is not a constant expression.
if (Info.getLangOpts().CPlusPlus0x)
- Info.CCEDiag(E->getExprLoc(), diag::note_constexpr_invalid_function)
+ Info.CCEDiag(E, diag::note_constexpr_invalid_function)
<< /*isConstexpr*/0 << /*isConstructor*/0 << "'strlen'";
else
- Info.CCEDiag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr);
+ Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
// Fall through.
case Builtin::BI__builtin_strlen:
// As an extension, we support strlen() and __builtin_strlen() as constant
@@ -4442,49 +4444,402 @@
return Result;
}
-bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
- if (E->isAssignmentOp())
- return Error(E);
+namespace {
- if (E->getOpcode() == BO_Comma) {
- VisitIgnoredValue(E->getLHS());
- return Visit(E->getRHS());
+/// \brief Data recursive integer evaluator of certain binary operators.
+///
+/// We use a data recursive algorithm for binary operators so that we are able
+/// to handle extreme cases of chained binary operators without causing stack
+/// overflow.
+class DataRecursiveIntBinOpEvaluator {
+ struct EvalResult {
+ APValue Val;
+ bool Failed;
+
+ EvalResult() : Failed(false) { }
+
+ void swap(EvalResult &RHS) {
+ Val.swap(RHS.Val);
+ Failed = RHS.Failed;
+ RHS.Failed = false;
+ }
+ };
+
+ struct Job {
+ const Expr *E;
+ EvalResult LHSResult; // meaningful only for binary operator expression.
+ enum { AnyExprKind, BinOpKind, BinOpVisitedLHSKind } Kind;
+
+ Job() : StoredInfo(0) { }
+ void startSpeculativeEval(EvalInfo &Info) {
+ OldEvalStatus = Info.EvalStatus;
+ Info.EvalStatus.Diag = 0;
+ StoredInfo = &Info;
+ }
+ ~Job() {
+ if (StoredInfo) {
+ StoredInfo->EvalStatus = OldEvalStatus;
+ }
+ }
+ private:
+ EvalInfo *StoredInfo; // non-null if status changed.
+ Expr::EvalStatus OldEvalStatus;
+ };
+
+ SmallVector<Job, 16> Queue;
+
+ IntExprEvaluator &IntEval;
+ EvalInfo &Info;
+ APValue &FinalResult;
+
+public:
+ DataRecursiveIntBinOpEvaluator(IntExprEvaluator &IntEval, APValue &Result)
+ : IntEval(IntEval), Info(IntEval.getEvalInfo()), FinalResult(Result) { }
+
+ /// \brief True if \param E is a binary operator that we are going to handle
+ /// data recursively.
+ /// We handle binary operators that are comma, logical, or that have operands
+ /// with integral or enumeration type.
+ static bool shouldEnqueue(const BinaryOperator *E) {
+ return E->getOpcode() == BO_Comma ||
+ E->isLogicalOp() ||
+ (E->getLHS()->getType()->isIntegralOrEnumerationType() &&
+ E->getRHS()->getType()->isIntegralOrEnumerationType());
}
- if (E->isLogicalOp()) {
- // These need to be handled specially because the operands aren't
- // necessarily integral nor evaluated.
- bool lhsResult, rhsResult;
+ bool Traverse(const BinaryOperator *E) {
+ enqueue(E);
+ EvalResult PrevResult;
+ while (!Queue.empty()) {
+ if (!process(PrevResult)) {
+ Queue.clear();
+ return false;
+ }
+ }
+
+ FinalResult.swap(PrevResult.Val);
+ return true;
+ }
+
+private:
+ bool Success(uint64_t Value, const Expr *E, APValue &Result) {
+ return IntEval.Success(Value, E, Result);
+ }
+ bool Success(const APSInt &Value, const Expr *E, APValue &Result) {
+ return IntEval.Success(Value, E, Result);
+ }
+ bool Error(const Expr *E) {
+ return IntEval.Error(E);
+ }
+ bool Error(const Expr *E, diag::kind D) {
+ return IntEval.Error(E, D);
+ }
+
+ OptionalDiagnostic CCEDiag(const Expr *E, diag::kind D) {
+ return Info.CCEDiag(E, D);
+ }
+
+ bool VisitBinOpLHSOnly(const EvalResult &LHSResult, const BinaryOperator *E,
+ bool &IgnoreRHS, APValue &Result,
+ bool &SuppressRHSDiags);
+
+ bool VisitBinOp(const EvalResult &LHSResult, const EvalResult &RHSResult,
+ const BinaryOperator *E, APValue &Result);
- if (EvaluateAsBooleanCondition(E->getLHS(), lhsResult, Info)) {
+ void EvaluateExpr(const Expr *E, EvalResult &Result) {
+ Result.Failed = !Evaluate(Result.Val, Info, E);
+ if (Result.Failed)
+ Result.Val = APValue();
+ }
+
+ bool process(EvalResult &Result);
+
+ void enqueue(const Expr *E) {
+ E = E->IgnoreParens();
+ Queue.resize(Queue.size()+1);
+ Queue.back().E = E;
+ Queue.back().Kind = Job::AnyExprKind;
+ }
+};
+
+}
+
+bool DataRecursiveIntBinOpEvaluator::
+ VisitBinOpLHSOnly(const EvalResult &LHSResult, const BinaryOperator *E,
+ bool &IgnoreRHS, APValue &Result,
+ bool &SuppressRHSDiags) {
+ if (E->getOpcode() == BO_Comma) {
+ // Ignore LHS but note if we could not evaluate it.
+ if (LHSResult.Failed)
+ Info.EvalStatus.HasSideEffects = true;
+ return true;
+ }
+
+ if (E->isLogicalOp()) {
+ bool lhsResult;
+ if (HandleConversionToBool(LHSResult.Val, lhsResult)) {
// We were able to evaluate the LHS, see if we can get away with not
// evaluating the RHS: 0 && X -> 0, 1 || X -> 1
- if (lhsResult == (E->getOpcode() == BO_LOr))
- return Success(lhsResult, E);
-
- if (EvaluateAsBooleanCondition(E->getRHS(), rhsResult, Info)) {
- if (E->getOpcode() == BO_LOr)
- return Success(lhsResult || rhsResult, E);
- else
- return Success(lhsResult && rhsResult, E);
+ if (lhsResult == (E->getOpcode() == BO_LOr)) {
+ IgnoreRHS = true;
+ return Success(lhsResult, E, Result);
}
} else {
// Since we weren't able to evaluate the left hand side, it
// must have had side effects.
Info.EvalStatus.HasSideEffects = true;
+
+ // We can't evaluate the LHS; however, sometimes the result
+ // is determined by the RHS: X && 0 -> 0, X || 1 -> 1.
+ // Don't ignore RHS and suppress diagnostics from this arm.
+ SuppressRHSDiags = true;
+ }
+
+ return true;
+ }
+
+ assert(E->getLHS()->getType()->isIntegralOrEnumerationType() &&
+ E->getRHS()->getType()->isIntegralOrEnumerationType());
+
+ if (LHSResult.Failed && !Info.keepEvaluatingAfterFailure())
+ return false;
+
+ return true;
+}
- // Suppress diagnostics from this arm.
- SpeculativeEvaluationRAII Speculative(Info);
- if (EvaluateAsBooleanCondition(E->getRHS(), rhsResult, Info)) {
+bool DataRecursiveIntBinOpEvaluator::
+ VisitBinOp(const EvalResult &LHSResult, const EvalResult &RHSResult,
+ const BinaryOperator *E, APValue &Result) {
+ if (E->getOpcode() == BO_Comma) {
+ if (RHSResult.Failed)
+ return false;
+ Result = RHSResult.Val;
+ return true;
+ }
+
+ if (E->isLogicalOp()) {
+ bool lhsResult, rhsResult;
+ bool LHSIsOK = HandleConversionToBool(LHSResult.Val, lhsResult);
+ bool RHSIsOK = HandleConversionToBool(RHSResult.Val, rhsResult);
+
+ if (LHSIsOK) {
+ if (RHSIsOK) {
+ if (E->getOpcode() == BO_LOr)
+ return Success(lhsResult || rhsResult, E, Result);
+ else
+ return Success(lhsResult && rhsResult, E, Result);
+ }
+ } else {
+ if (RHSIsOK) {
// We can't evaluate the LHS; however, sometimes the result
// is determined by the RHS: X && 0 -> 0, X || 1 -> 1.
if (rhsResult == (E->getOpcode() == BO_LOr))
- return Success(rhsResult, E);
+ return Success(rhsResult, E, Result);
}
}
-
+
return false;
}
+
+ assert(E->getLHS()->getType()->isIntegralOrEnumerationType() &&
+ E->getRHS()->getType()->isIntegralOrEnumerationType());
+
+ if (LHSResult.Failed || RHSResult.Failed)
+ return false;
+
+ const APValue &LHSVal = LHSResult.Val;
+ const APValue &RHSVal = RHSResult.Val;
+
+ // Handle cases like (unsigned long)&a + 4.
+ if (E->isAdditiveOp() && LHSVal.isLValue() && RHSVal.isInt()) {
+ Result = LHSVal;
+ CharUnits AdditionalOffset = CharUnits::fromQuantity(
+ RHSVal.getInt().getZExtValue());
+ if (E->getOpcode() == BO_Add)
+ Result.getLValueOffset() += AdditionalOffset;
+ else
+ Result.getLValueOffset() -= AdditionalOffset;
+ return true;
+ }
+
+ // Handle cases like 4 + (unsigned long)&a
+ if (E->getOpcode() == BO_Add &&
+ RHSVal.isLValue() && LHSVal.isInt()) {
+ Result = RHSVal;
+ Result.getLValueOffset() += CharUnits::fromQuantity(
+ LHSVal.getInt().getZExtValue());
+ return true;
+ }
+
+ if (E->getOpcode() == BO_Sub && LHSVal.isLValue() && RHSVal.isLValue()) {
+ // Handle (intptr_t)&&A - (intptr_t)&&B.
+ if (!LHSVal.getLValueOffset().isZero() ||
+ !RHSVal.getLValueOffset().isZero())
+ return false;
+ const Expr *LHSExpr = LHSVal.getLValueBase().dyn_cast<const Expr*>();
+ const Expr *RHSExpr = RHSVal.getLValueBase().dyn_cast<const Expr*>();
+ if (!LHSExpr || !RHSExpr)
+ return false;
+ const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
+ const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
+ if (!LHSAddrExpr || !RHSAddrExpr)
+ return false;
+ // Make sure both labels come from the same function.
+ if (LHSAddrExpr->getLabel()->getDeclContext() !=
+ RHSAddrExpr->getLabel()->getDeclContext())
+ return false;
+ Result = APValue(LHSAddrExpr, RHSAddrExpr);
+ return true;
+ }
+
+ // All the following cases expect both operands to be an integer
+ if (!LHSVal.isInt() || !RHSVal.isInt())
+ return Error(E);
+
+ const APSInt &LHS = LHSVal.getInt();
+ APSInt RHS = RHSVal.getInt();
+
+ switch (E->getOpcode()) {
+ default:
+ return Error(E);
+ case BO_Mul:
+ return Success(CheckedIntArithmetic(Info, E, LHS, RHS,
+ LHS.getBitWidth() * 2,
+ std::multiplies<APSInt>()), E,
+ Result);
+ case BO_Add:
+ return Success(CheckedIntArithmetic(Info, E, LHS, RHS,
+ LHS.getBitWidth() + 1,
+ std::plus<APSInt>()), E, Result);
+ case BO_Sub:
+ return Success(CheckedIntArithmetic(Info, E, LHS, RHS,
+ LHS.getBitWidth() + 1,
+ std::minus<APSInt>()), E, Result);
+ case BO_And: return Success(LHS & RHS, E, Result);
+ case BO_Xor: return Success(LHS ^ RHS, E, Result);
+ case BO_Or: return Success(LHS | RHS, E, Result);
+ case BO_Div:
+ case BO_Rem:
+ if (RHS == 0)
+ return Error(E, diag::note_expr_divide_by_zero);
+ // Check for overflow case: INT_MIN / -1 or INT_MIN % -1. The latter is
+ // not actually undefined behavior in C++11 due to a language defect.
+ if (RHS.isNegative() && RHS.isAllOnesValue() &&
+ LHS.isSigned() && LHS.isMinSignedValue())
+ HandleOverflow(Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->getType());
+ return Success(E->getOpcode() == BO_Rem ? LHS % RHS : LHS / RHS, E,
+ Result);
+ case BO_Shl: {
+ // During constant-folding, a negative shift is an opposite shift. Such
+ // a shift is not a constant expression.
+ if (RHS.isSigned() && RHS.isNegative()) {
+ CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
+ RHS = -RHS;
+ goto shift_right;
+ }
+
+ shift_left:
+ // C++11 [expr.shift]p1: Shift width must be less than the bit width of
+ // the shifted type.
+ unsigned SA = (unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
+ if (SA != RHS) {
+ CCEDiag(E, diag::note_constexpr_large_shift)
+ << RHS << E->getType() << LHS.getBitWidth();
+ } else if (LHS.isSigned()) {
+ // C++11 [expr.shift]p2: A signed left shift must have a non-negative
+ // operand, and must not overflow the corresponding unsigned type.
+ if (LHS.isNegative())
+ CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
+ else if (LHS.countLeadingZeros() < SA)
+ CCEDiag(E, diag::note_constexpr_lshift_discards);
+ }
+
+ return Success(LHS << SA, E, Result);
+ }
+ case BO_Shr: {
+ // During constant-folding, a negative shift is an opposite shift. Such a
+ // shift is not a constant expression.
+ if (RHS.isSigned() && RHS.isNegative()) {
+ CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
+ RHS = -RHS;
+ goto shift_left;
+ }
+
+ shift_right:
+ // C++11 [expr.shift]p1: Shift width must be less than the bit width of the
+ // shifted type.
+ unsigned SA = (unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
+ if (SA != RHS)
+ CCEDiag(E, diag::note_constexpr_large_shift)
+ << RHS << E->getType() << LHS.getBitWidth();
+
+ return Success(LHS >> SA, E, Result);
+ }
+
+ case BO_LT: return Success(LHS < RHS, E, Result);
+ case BO_GT: return Success(LHS > RHS, E, Result);
+ case BO_LE: return Success(LHS <= RHS, E, Result);
+ case BO_GE: return Success(LHS >= RHS, E, Result);
+ case BO_EQ: return Success(LHS == RHS, E, Result);
+ case BO_NE: return Success(LHS != RHS, E, Result);
+ }
+}
+
+bool DataRecursiveIntBinOpEvaluator::process(EvalResult &Result) {
+ Job &job = Queue.back();
+
+ switch (job.Kind) {
+ case Job::AnyExprKind: {
+ if (const BinaryOperator *Bop = dyn_cast<BinaryOperator>(job.E)) {
+ if (shouldEnqueue(Bop)) {
+ job.Kind = Job::BinOpKind;
+ enqueue(Bop->getLHS());
+ return true;
+ }
+ }
+
+ EvaluateExpr(job.E, Result);
+ Queue.pop_back();
+ return true;
+ }
+
+ case Job::BinOpKind: {
+ const BinaryOperator *Bop = cast<BinaryOperator>(job.E);
+ job.LHSResult.swap(Result);
+ bool IgnoreRHS = false;
+ bool SuppressRHSDiags = false;
+ bool ret = VisitBinOpLHSOnly(job.LHSResult, Bop, IgnoreRHS, Result.Val,
+ SuppressRHSDiags);
+ if (IgnoreRHS) {
+ Queue.pop_back();
+ return ret;
+ }
+ if (SuppressRHSDiags)
+ job.startSpeculativeEval(Info);
+ job.Kind = Job::BinOpVisitedLHSKind;
+ enqueue(Bop->getRHS());
+ return ret;
+ }
+
+ case Job::BinOpVisitedLHSKind: {
+ const BinaryOperator *Bop = cast<BinaryOperator>(job.E);
+ EvalResult RHS;
+ RHS.swap(Result);
+ bool ret = VisitBinOp(job.LHSResult, RHS, Bop, Result.Val);
+ Queue.pop_back();
+ return ret;
+ }
+ }
+
+ llvm_unreachable("Invalid Job::Kind!");
+}
+
+bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
+ if (E->isAssignmentOp())
+ return Error(E);
+
+ if (DataRecursiveIntBinOpEvaluator::shouldEnqueue(E))
+ return DataRecursiveIntBinOpEvaluator(*this, Result).Traverse(E);
QualType LHSTy = E->getLHS()->getType();
QualType RHSTy = E->getRHS()->getType();
@@ -4785,155 +5140,11 @@
return Success(Opcode == BO_EQ || Opcode == BO_LE || Opcode == BO_GE, E);
}
- if (!LHSTy->isIntegralOrEnumerationType() ||
- !RHSTy->isIntegralOrEnumerationType()) {
- // We can't continue from here for non-integral types.
- return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
- }
-
- // The LHS of a constant expr is always evaluated and needed.
- APValue LHSVal;
-
- bool LHSOK = EvaluateIntegerOrLValue(E->getLHS(), LHSVal, Info);
- if (!LHSOK && !Info.keepEvaluatingAfterFailure())
- return false;
-
- if (!Visit(E->getRHS()) || !LHSOK)
- return false;
-
- APValue &RHSVal = Result;
-
- // Handle cases like (unsigned long)&a + 4.
- if (E->isAdditiveOp() && LHSVal.isLValue() && RHSVal.isInt()) {
- CharUnits AdditionalOffset = CharUnits::fromQuantity(
- RHSVal.getInt().getZExtValue());
- if (E->getOpcode() == BO_Add)
- LHSVal.getLValueOffset() += AdditionalOffset;
- else
- LHSVal.getLValueOffset() -= AdditionalOffset;
- Result = LHSVal;
- return true;
- }
-
- // Handle cases like 4 + (unsigned long)&a
- if (E->getOpcode() == BO_Add &&
- RHSVal.isLValue() && LHSVal.isInt()) {
- RHSVal.getLValueOffset() += CharUnits::fromQuantity(
- LHSVal.getInt().getZExtValue());
- // Note that RHSVal is Result.
- return true;
- }
-
- if (E->getOpcode() == BO_Sub && LHSVal.isLValue() && RHSVal.isLValue()) {
- // Handle (intptr_t)&&A - (intptr_t)&&B.
- if (!LHSVal.getLValueOffset().isZero() ||
- !RHSVal.getLValueOffset().isZero())
- return false;
- const Expr *LHSExpr = LHSVal.getLValueBase().dyn_cast<const Expr*>();
- const Expr *RHSExpr = RHSVal.getLValueBase().dyn_cast<const Expr*>();
- if (!LHSExpr || !RHSExpr)
- return false;
- const AddrLabelExpr *LHSAddrExpr = dyn_cast<AddrLabelExpr>(LHSExpr);
- const AddrLabelExpr *RHSAddrExpr = dyn_cast<AddrLabelExpr>(RHSExpr);
- if (!LHSAddrExpr || !RHSAddrExpr)
- return false;
- // Make sure both labels come from the same function.
- if (LHSAddrExpr->getLabel()->getDeclContext() !=
- RHSAddrExpr->getLabel()->getDeclContext())
- return false;
- Result = APValue(LHSAddrExpr, RHSAddrExpr);
- return true;
- }
-
- // All the following cases expect both operands to be an integer
- if (!LHSVal.isInt() || !RHSVal.isInt())
- return Error(E);
-
- APSInt &LHS = LHSVal.getInt();
- APSInt &RHS = RHSVal.getInt();
-
- switch (E->getOpcode()) {
- default:
- return Error(E);
- case BO_Mul:
- return Success(CheckedIntArithmetic(Info, E, LHS, RHS,
- LHS.getBitWidth() * 2,
- std::multiplies<APSInt>()), E);
- case BO_Add:
- return Success(CheckedIntArithmetic(Info, E, LHS, RHS,
- LHS.getBitWidth() + 1,
- std::plus<APSInt>()), E);
- case BO_Sub:
- return Success(CheckedIntArithmetic(Info, E, LHS, RHS,
- LHS.getBitWidth() + 1,
- std::minus<APSInt>()), E);
- case BO_And: return Success(LHS & RHS, E);
- case BO_Xor: return Success(LHS ^ RHS, E);
- case BO_Or: return Success(LHS | RHS, E);
- case BO_Div:
- case BO_Rem:
- if (RHS == 0)
- return Error(E, diag::note_expr_divide_by_zero);
- // Check for overflow case: INT_MIN / -1 or INT_MIN % -1. The latter is not
- // actually undefined behavior in C++11 due to a language defect.
- if (RHS.isNegative() && RHS.isAllOnesValue() &&
- LHS.isSigned() && LHS.isMinSignedValue())
- HandleOverflow(Info, E, -LHS.extend(LHS.getBitWidth() + 1), E->getType());
- return Success(E->getOpcode() == BO_Rem ? LHS % RHS : LHS / RHS, E);
- case BO_Shl: {
- // During constant-folding, a negative shift is an opposite shift. Such a
- // shift is not a constant expression.
- if (RHS.isSigned() && RHS.isNegative()) {
- CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
- RHS = -RHS;
- goto shift_right;
- }
-
- shift_left:
- // C++11 [expr.shift]p1: Shift width must be less than the bit width of the
- // shifted type.
- unsigned SA = (unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
- if (SA != RHS) {
- CCEDiag(E, diag::note_constexpr_large_shift)
- << RHS << E->getType() << LHS.getBitWidth();
- } else if (LHS.isSigned()) {
- // C++11 [expr.shift]p2: A signed left shift must have a non-negative
- // operand, and must not overflow the corresponding unsigned type.
- if (LHS.isNegative())
- CCEDiag(E, diag::note_constexpr_lshift_of_negative) << LHS;
- else if (LHS.countLeadingZeros() < SA)
- CCEDiag(E, diag::note_constexpr_lshift_discards);
- }
-
- return Success(LHS << SA, E);
- }
- case BO_Shr: {
- // During constant-folding, a negative shift is an opposite shift. Such a
- // shift is not a constant expression.
- if (RHS.isSigned() && RHS.isNegative()) {
- CCEDiag(E, diag::note_constexpr_negative_shift) << RHS;
- RHS = -RHS;
- goto shift_left;
- }
-
- shift_right:
- // C++11 [expr.shift]p1: Shift width must be less than the bit width of the
- // shifted type.
- unsigned SA = (unsigned) RHS.getLimitedValue(LHS.getBitWidth()-1);
- if (SA != RHS)
- CCEDiag(E, diag::note_constexpr_large_shift)
- << RHS << E->getType() << LHS.getBitWidth();
-
- return Success(LHS >> SA, E);
- }
-
- case BO_LT: return Success(LHS < RHS, E);
- case BO_GT: return Success(LHS > RHS, E);
- case BO_LE: return Success(LHS <= RHS, E);
- case BO_GE: return Success(LHS >= RHS, E);
- case BO_EQ: return Success(LHS == RHS, E);
- case BO_NE: return Success(LHS != RHS, E);
- }
+ assert((!LHSTy->isIntegralOrEnumerationType() ||
+ !RHSTy->isIntegralOrEnumerationType()) &&
+ "DataRecursiveIntBinOpEvaluator should have handled integral types");
+ // We can't continue from here for non-integral types.
+ return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
}
CharUnits IntExprEvaluator::GetAlignOfType(QualType T) {
@@ -5980,17 +6191,17 @@
Result = Info.CurrentCall->Temporaries[E];
} else if (E->getType()->isVoidType()) {
if (Info.getLangOpts().CPlusPlus0x)
- Info.CCEDiag(E->getExprLoc(), diag::note_constexpr_nonliteral)
+ Info.CCEDiag(E, diag::note_constexpr_nonliteral)
<< E->getType();
else
- Info.CCEDiag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr);
+ Info.CCEDiag(E, diag::note_invalid_subexpr_in_const_expr);
if (!EvaluateVoid(E, Info))
return false;
} else if (Info.getLangOpts().CPlusPlus0x) {
- Info.Diag(E->getExprLoc(), diag::note_constexpr_nonliteral) << E->getType();
+ Info.Diag(E, diag::note_constexpr_nonliteral) << E->getType();
return false;
} else {
- Info.Diag(E->getExprLoc(), diag::note_invalid_subexpr_in_const_expr);
+ Info.Diag(E, diag::note_invalid_subexpr_in_const_expr);
return false;
}
@@ -6056,7 +6267,7 @@
// FIXME: Evaluating values of large array and record types can cause
// performance problems. Only do so in C++11 for now.
if (isRValue() && (getType()->isArrayType() || getType()->isRecordType()) &&
- !Ctx.getLangOptions().CPlusPlus0x)
+ !Ctx.getLangOpts().CPlusPlus0x)
return false;
EvalInfo Info(Ctx, Result);
@@ -6103,7 +6314,7 @@
// FIXME: Evaluating initializers for large array and record types can cause
// performance problems. Only do so in C++11 for now.
if (isRValue() && (getType()->isArrayType() || getType()->isRecordType()) &&
- !Ctx.getLangOptions().CPlusPlus0x)
+ !Ctx.getLangOpts().CPlusPlus0x)
return false;
Expr::EvalStatus EStatus;
@@ -6119,7 +6330,7 @@
// Variables with static storage duration or thread storage duration shall be
// zero-initialized before any other initialization takes place.
// This behavior is not present in C.
- if (Ctx.getLangOptions().CPlusPlus && !VD->hasLocalStorage() &&
+ if (Ctx.getLangOpts().CPlusPlus && !VD->hasLocalStorage() &&
!VD->getType()->isReferenceType()) {
ImplicitValueInitExpr VIE(VD->getType());
if (!EvaluateInPlace(Value, InitInfo, LVal, &VIE, CCEK_Constant,
@@ -6272,7 +6483,6 @@
case Expr::ObjCIsaExprClass:
case Expr::ShuffleVectorExprClass:
case Expr::BlockExprClass:
- case Expr::BlockDeclRefExprClass:
case Expr::NoStmtClass:
case Expr::OpaqueValueExprClass:
case Expr::PackExpansionExprClass:
@@ -6325,7 +6535,7 @@
if (isa<EnumConstantDecl>(cast<DeclRefExpr>(E)->getDecl()))
return NoDiag();
const ValueDecl *D = dyn_cast<ValueDecl>(cast<DeclRefExpr>(E)->getDecl());
- if (Ctx.getLangOptions().CPlusPlus &&
+ if (Ctx.getLangOpts().CPlusPlus &&
D && IsConstNonVolatile(D->getType())) {
// Parameter variables are never constants. Without this check,
// getAnyInitializer() can find a default argument, which leads
@@ -6448,7 +6658,7 @@
}
}
if (Exp->getOpcode() == BO_Comma) {
- if (Ctx.getLangOptions().C99) {
+ if (Ctx.getLangOpts().C99) {
// C99 6.6p3 introduces a strange edge case: comma can be in an ICE
// if it isn't evaluated.
if (LHSResult.Val == 0 && RHSResult.Val == 0)
@@ -6593,7 +6803,7 @@
}
bool Expr::isIntegerConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const {
- if (Ctx.getLangOptions().CPlusPlus0x)
+ if (Ctx.getLangOpts().CPlusPlus0x)
return EvaluateCPlusPlus11IntegralConstantExpr(Ctx, this, 0, Loc);
ICEDiag d = CheckICE(this, Ctx);
@@ -6606,7 +6816,7 @@
bool Expr::isIntegerConstantExpr(llvm::APSInt &Value, ASTContext &Ctx,
SourceLocation *Loc, bool isEvaluated) const {
- if (Ctx.getLangOptions().CPlusPlus0x)
+ if (Ctx.getLangOpts().CPlusPlus0x)
return EvaluateCPlusPlus11IntegralConstantExpr(Ctx, this, &Value, Loc);
if (!isIntegerConstantExpr(Ctx, Loc))
@@ -6624,7 +6834,7 @@
SourceLocation *Loc) const {
// We support this checking in C++98 mode in order to diagnose compatibility
// issues.
- assert(Ctx.getLangOptions().CPlusPlus);
+ assert(Ctx.getLangOpts().CPlusPlus);
// Build evaluation settings.
Expr::EvalStatus Status;
Modified: cfe/branches/tooling/lib/AST/ItaniumMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/ItaniumMangle.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/branches/tooling/lib/AST/ItaniumMangle.cpp Mon Mar 19 14:02:20 2012
@@ -375,7 +375,7 @@
bool ItaniumMangleContext::shouldMangleDeclName(const NamedDecl *D) {
// In C, functions with no attributes never need to be mangled. Fastpath them.
- if (!getASTContext().getLangOptions().CPlusPlus && !D->hasAttrs())
+ if (!getASTContext().getLangOpts().CPlusPlus && !D->hasAttrs())
return false;
// Any decl can be declared with __asm("foo") on it, and this takes precedence
@@ -392,7 +392,7 @@
return true;
// Otherwise, no mangling is done outside C++ mode.
- if (!getASTContext().getLangOptions().CPlusPlus)
+ if (!getASTContext().getLangOpts().CPlusPlus)
return false;
// Variables at global scope with non-internal linkage are not mangled
@@ -2351,7 +2351,6 @@
// These all can only appear in local or variable-initialization
// contexts and so should never appear in a mangling.
case Expr::AddrLabelExprClass:
- case Expr::BlockDeclRefExprClass:
case Expr::CXXThisExprClass:
case Expr::DesignatedInitExprClass:
case Expr::ImplicitValueInitExprClass:
Modified: cfe/branches/tooling/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/MicrosoftMangle.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/branches/tooling/lib/AST/MicrosoftMangle.cpp Mon Mar 19 14:02:20 2012
@@ -119,7 +119,7 @@
bool MicrosoftMangleContext::shouldMangleDeclName(const NamedDecl *D) {
// In C, functions with no attributes never need to be mangled. Fastpath them.
- if (!getASTContext().getLangOptions().CPlusPlus && !D->hasAttrs())
+ if (!getASTContext().getLangOpts().CPlusPlus && !D->hasAttrs())
return false;
// Any decl can be declared with __asm("foo") on it, and this takes precedence
@@ -136,7 +136,7 @@
return true;
// Otherwise, no mangling is done outside C++ mode.
- if (!getASTContext().getLangOptions().CPlusPlus)
+ if (!getASTContext().getLangOpts().CPlusPlus)
return false;
// Variables at global scope with internal linkage are not mangled.
Modified: cfe/branches/tooling/lib/AST/NestedNameSpecifier.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/NestedNameSpecifier.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/NestedNameSpecifier.cpp (original)
+++ cfe/branches/tooling/lib/AST/NestedNameSpecifier.cpp Mon Mar 19 14:02:20 2012
@@ -434,9 +434,6 @@
}
}
-NestedNameSpecifierLocBuilder::NestedNameSpecifierLocBuilder()
- : Representation(0), Buffer(0), BufferSize(0), BufferCapacity(0) { }
-
NestedNameSpecifierLocBuilder::
NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other)
: Representation(Other.Representation), Buffer(0),
@@ -499,11 +496,6 @@
return *this;
}
-NestedNameSpecifierLocBuilder::~NestedNameSpecifierLocBuilder() {
- if (BufferCapacity)
- free(Buffer);
-}
-
void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
SourceLocation TemplateKWLoc,
TypeLoc TL,
Modified: cfe/branches/tooling/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/RecordLayoutBuilder.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/branches/tooling/lib/AST/RecordLayoutBuilder.cpp Mon Mar 19 14:02:20 2012
@@ -1396,7 +1396,7 @@
IsMsStruct = D->hasAttr<MsStructAttr>();
// Honor the default struct packing maximum alignment flag.
- if (unsigned DefaultMaxFieldAlignment = Context.getLangOptions().PackStruct) {
+ if (unsigned DefaultMaxFieldAlignment = Context.getLangOpts().PackStruct) {
MaxFieldAlignment = CharUnits::fromQuantity(DefaultMaxFieldAlignment);
}
@@ -1658,7 +1658,7 @@
uint64_t TypeSize,
bool FieldPacked,
const FieldDecl *D) {
- assert(Context.getLangOptions().CPlusPlus &&
+ assert(Context.getLangOpts().CPlusPlus &&
"Can only have wide bit-fields in C++!");
// Itanium C++ ABI 2.4:
@@ -1900,7 +1900,7 @@
ZeroLengthBitfield = 0;
}
- if (Context.getLangOptions().MSBitfields || IsMsStruct) {
+ if (Context.getLangOpts().MSBitfields || IsMsStruct) {
// If MS bitfield layout is required, figure out what type is being
// laid out and align the field to the width of that type.
@@ -1987,7 +1987,7 @@
}
// In C++, records cannot be of size 0.
- if (Context.getLangOptions().CPlusPlus && getSizeInBits() == 0) {
+ if (Context.getLangOpts().CPlusPlus && getSizeInBits() == 0) {
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
// Compatibility with gcc requires a class (pod or non-pod)
// which is not empty but of size 0; such as having fields of
@@ -2263,9 +2263,9 @@
ASTRecordLayouts[D] = NewEntry;
- if (getLangOptions().DumpRecordLayouts) {
+ if (getLangOpts().DumpRecordLayouts) {
llvm::errs() << "\n*** Dumping AST Record Layout\n";
- DumpRecordLayout(D, llvm::errs(), getLangOptions().DumpRecordLayoutsSimple);
+ DumpRecordLayout(D, llvm::errs(), getLangOpts().DumpRecordLayoutsSimple);
}
return *NewEntry;
@@ -2313,6 +2313,8 @@
ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
const ObjCImplementationDecl *Impl) const {
// Retrieve the definition
+ if (D->hasExternalLexicalStorage() && !D->getDefinition())
+ getExternalSource()->CompleteType(const_cast<ObjCInterfaceDecl*>(D));
D = D->getDefinition();
assert(D && D->isThisDeclarationADefinition() && "Invalid interface decl!");
Modified: cfe/branches/tooling/lib/AST/Stmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/Stmt.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/Stmt.cpp (original)
+++ cfe/branches/tooling/lib/AST/Stmt.cpp Mon Mar 19 14:02:20 2012
@@ -176,6 +176,72 @@
llvm_unreachable("unknown statement kind!");
}
+// Amusing macro metaprogramming hack: check whether a class provides
+// a more specific implementation of getLocStart() and getLocEnd().
+//
+// See also Expr.cpp:getExprLoc().
+namespace {
+ /// This implementation is used when a class provides a custom
+ /// implementation of getLocStart.
+ template <class S, class T>
+ SourceLocation getLocStartImpl(const Stmt *stmt,
+ SourceLocation (T::*v)() const) {
+ return static_cast<const S*>(stmt)->getLocStart();
+ }
+
+ /// This implementation is used when a class doesn't provide a custom
+ /// implementation of getLocStart. Overload resolution should pick it over
+ /// the implementation above because it's more specialized according to
+ /// function template partial ordering.
+ template <class S>
+ SourceLocation getLocStartImpl(const Stmt *stmt,
+ SourceLocation (Stmt::*v)() const) {
+ return static_cast<const S*>(stmt)->getSourceRange().getBegin();
+ }
+
+ /// This implementation is used when a class provides a custom
+ /// implementation of getLocEnd.
+ template <class S, class T>
+ SourceLocation getLocEndImpl(const Stmt *stmt,
+ SourceLocation (T::*v)() const) {
+ return static_cast<const S*>(stmt)->getLocEnd();
+ }
+
+ /// This implementation is used when a class doesn't provide a custom
+ /// implementation of getLocEnd. Overload resolution should pick it over
+ /// the implementation above because it's more specialized according to
+ /// function template partial ordering.
+ template <class S>
+ SourceLocation getLocEndImpl(const Stmt *stmt,
+ SourceLocation (Stmt::*v)() const) {
+ return static_cast<const S*>(stmt)->getSourceRange().getEnd();
+ }
+}
+
+SourceLocation Stmt::getLocStart() const {
+ switch (getStmtClass()) {
+ case Stmt::NoStmtClass: llvm_unreachable("statement without class");
+#define ABSTRACT_STMT(type)
+#define STMT(type, base) \
+ case Stmt::type##Class: \
+ return getLocStartImpl<type>(this, &type::getLocStart);
+#include "clang/AST/StmtNodes.inc"
+ }
+ llvm_unreachable("unknown statement kind");
+}
+
+SourceLocation Stmt::getLocEnd() const {
+ switch (getStmtClass()) {
+ case Stmt::NoStmtClass: llvm_unreachable("statement without class");
+#define ABSTRACT_STMT(type)
+#define STMT(type, base) \
+ case Stmt::type##Class: \
+ return getLocEndImpl<type>(this, &type::getLocEnd);
+#include "clang/AST/StmtNodes.inc"
+ }
+ llvm_unreachable("unknown statement kind");
+}
+
void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) {
if (this->Body)
C.Deallocate(Body);
@@ -627,9 +693,9 @@
return;
}
- SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V),
- V->getSourceRange().getBegin(),
- V->getSourceRange().getEnd());
+ SourceRange VarRange = V->getSourceRange();
+ SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
+ VarRange.getEnd());
}
ForStmt::ForStmt(ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
@@ -658,9 +724,9 @@
return;
}
- SubExprs[CONDVAR] = new (C) DeclStmt(DeclGroupRef(V),
- V->getSourceRange().getBegin(),
- V->getSourceRange().getEnd());
+ SourceRange VarRange = V->getSourceRange();
+ SubExprs[CONDVAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
+ VarRange.getEnd());
}
SwitchStmt::SwitchStmt(ASTContext &C, VarDecl *Var, Expr *cond)
@@ -685,9 +751,9 @@
return;
}
- SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V),
- V->getSourceRange().getBegin(),
- V->getSourceRange().getEnd());
+ SourceRange VarRange = V->getSourceRange();
+ SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
+ VarRange.getEnd());
}
Stmt *SwitchCase::getSubStmt() {
@@ -718,10 +784,10 @@
SubExprs[VAR] = 0;
return;
}
-
- SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V),
- V->getSourceRange().getBegin(),
- V->getSourceRange().getEnd());
+
+ SourceRange VarRange = V->getSourceRange();
+ SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
+ VarRange.getEnd());
}
// IndirectGotoStmt
Modified: cfe/branches/tooling/lib/AST/StmtDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/StmtDumper.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/StmtDumper.cpp (original)
+++ cfe/branches/tooling/lib/AST/StmtDumper.cpp Mon Mar 19 14:02:20 2012
@@ -254,7 +254,7 @@
std::string Name = VD->getNameAsString();
VD->getType().getAsStringInternal(Name,
- PrintingPolicy(VD->getASTContext().getLangOptions()));
+ PrintingPolicy(VD->getASTContext().getLangOpts()));
OS << Name;
// If this is a vardecl with an initializer, emit it.
@@ -287,7 +287,7 @@
const char *tn = UD->isTypeName() ? "typename " : "";
OS << '"' << UD->getDeclKindName() << tn;
UD->getQualifier()->print(OS,
- PrintingPolicy(UD->getASTContext().getLangOptions()));
+ PrintingPolicy(UD->getASTContext().getLangOpts()));
OS << ";\"";
} else if (LabelDecl *LD = dyn_cast<LabelDecl>(D)) {
OS << "label " << *LD;
@@ -507,8 +507,10 @@
void StmtDumper::VisitBlockExpr(BlockExpr *Node) {
DumpExpr(Node);
- IndentLevel++;
BlockDecl *block = Node->getBlockDecl();
+ OS << " decl=" << block;
+
+ IndentLevel++;
if (block->capturesCXXThis()) {
OS << '\n'; Indent(); OS << "(capture this)";
}
@@ -526,6 +528,7 @@
}
IndentLevel--;
+ OS << '\n';
DumpSubTree(block->getBody());
}
Modified: cfe/branches/tooling/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/StmtPrinter.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/StmtPrinter.cpp (original)
+++ cfe/branches/tooling/lib/AST/StmtPrinter.cpp Mon Mar 19 14:02:20 2012
@@ -1225,14 +1225,17 @@
void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {
switch (Node->getLiteralOperatorKind()) {
case UserDefinedLiteral::LOK_Raw:
- OS << cast<StringLiteral>(Node->getArg(0))->getString();
+ OS << cast<StringLiteral>(Node->getArg(0)->IgnoreImpCasts())->getString();
break;
case UserDefinedLiteral::LOK_Template: {
- DeclRefExpr *DRE = cast<DeclRefExpr>(Node->getCallee());
- assert(DRE->hasExplicitTemplateArgs());
- const TemplateArgumentLoc *Args = DRE->getTemplateArgs();
- for (unsigned i = 0, e = DRE->getNumTemplateArgs(); i != e; ++i) {
- char C = (char)Args[i].getArgument().getAsIntegral()->getZExtValue();
+ DeclRefExpr *DRE = cast<DeclRefExpr>(Node->getCallee()->IgnoreImpCasts());
+ const TemplateArgumentList *Args =
+ cast<FunctionDecl>(DRE->getDecl())->getTemplateSpecializationArgs();
+ assert(Args);
+ const TemplateArgument &Pack = Args->get(0);
+ for (TemplateArgument::pack_iterator I = Pack.pack_begin(),
+ E = Pack.pack_end(); I != E; ++I) {
+ char C = (char)I->getAsIntegral()->getZExtValue();
OS << C;
}
break;
@@ -1813,10 +1816,6 @@
}
}
-void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) {
- OS << *Node->getDecl();
-}
-
void StmtPrinter::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
PrintExpr(Node->getSourceExpr());
}
@@ -1834,7 +1833,7 @@
void Stmt::dumpPretty(ASTContext& Context) const {
printPretty(llvm::errs(), Context, 0,
- PrintingPolicy(Context.getLangOptions()));
+ PrintingPolicy(Context.getLangOpts()));
}
void Stmt::printPretty(raw_ostream &OS, ASTContext& Context,
Modified: cfe/branches/tooling/lib/AST/StmtProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/StmtProfile.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/StmtProfile.cpp (original)
+++ cfe/branches/tooling/lib/AST/StmtProfile.cpp Mon Mar 19 14:02:20 2012
@@ -460,13 +460,6 @@
VisitDecl(S->getBlockDecl());
}
-void StmtProfiler::VisitBlockDeclRefExpr(const BlockDeclRefExpr *S) {
- VisitExpr(S);
- VisitDecl(S->getDecl());
- ID.AddBoolean(S->isByRef());
- ID.AddBoolean(S->isConstQualAdded());
-}
-
void StmtProfiler::VisitGenericSelectionExpr(const GenericSelectionExpr *S) {
VisitExpr(S);
for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
Modified: cfe/branches/tooling/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/Type.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/Type.cpp (original)
+++ cfe/branches/tooling/lib/AST/Type.cpp Mon Mar 19 14:02:20 2012
@@ -309,13 +309,6 @@
}
}
-/// 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::isDerivedType() const {
switch (CanonicalType->getTypeClass()) {
case Pointer:
@@ -587,7 +580,7 @@
return BT->getKind() >= BuiltinType::Bool &&
BT->getKind() <= BuiltinType::Int128;
- if (!Ctx.getLangOptions().CPlusPlus)
+ if (!Ctx.getLangOpts().CPlusPlus)
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
return ET->getDecl()->isComplete(); // Complete enum types are integral in C.
@@ -914,7 +907,7 @@
if ((*this)->isIncompleteType())
return false;
- if (Context.getLangOptions().ObjCAutoRefCount) {
+ if (Context.getLangOpts().ObjCAutoRefCount) {
switch (getObjCLifetime()) {
case Qualifiers::OCL_ExplicitNone:
return true;
@@ -976,7 +969,7 @@
if ((*this)->isIncompleteType())
return false;
- if (Context.getLangOptions().ObjCAutoRefCount) {
+ if (Context.getLangOpts().ObjCAutoRefCount) {
switch (getObjCLifetime()) {
case Qualifiers::OCL_ExplicitNone:
return true;
@@ -1026,7 +1019,7 @@
if ((*this)->isArrayType())
return Context.getBaseElementType(*this).isTrivialType(Context);
- if (Context.getLangOptions().ObjCAutoRefCount) {
+ if (Context.getLangOpts().ObjCAutoRefCount) {
switch (getObjCLifetime()) {
case Qualifiers::OCL_ExplicitNone:
return true;
@@ -1171,7 +1164,7 @@
if (ty->isDependentType())
return false;
- if (Context.getLangOptions().ObjCAutoRefCount) {
+ if (Context.getLangOpts().ObjCAutoRefCount) {
switch (getObjCLifetime()) {
case Qualifiers::OCL_ExplicitNone:
return true;
@@ -1474,7 +1467,7 @@
// have cv-unqualified types.
//
// See also C99 6.3.2.1p2.
- if (!Context.getLangOptions().CPlusPlus ||
+ if (!Context.getLangOpts().CPlusPlus ||
(!getTypePtr()->isDependentType() && !getTypePtr()->isRecordType()))
return getUnqualifiedType();
@@ -2241,7 +2234,7 @@
case Qualifiers::OCL_Autoreleasing:
case Qualifiers::OCL_Strong:
case Qualifiers::OCL_Weak:
- return !Context.getLangOptions().ObjCAutoRefCount;
+ return !Context.getLangOpts().ObjCAutoRefCount;
}
if (const CXXRecordDecl *Record
Modified: cfe/branches/tooling/lib/AST/VTableBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/VTableBuilder.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/VTableBuilder.cpp (original)
+++ cfe/branches/tooling/lib/AST/VTableBuilder.cpp Mon Mar 19 14:02:20 2012
@@ -996,7 +996,7 @@
LayoutVTable();
- if (Context.getLangOptions().DumpVTableLayouts)
+ if (Context.getLangOpts().DumpVTableLayouts)
dumpLayout(llvm::errs());
}
@@ -1580,7 +1580,7 @@
LayoutVTablesForVirtualBases(MostDerivedClass, VBases);
// -fapple-kext adds an extra entry at end of vtbl.
- bool IsAppleKext = Context.getLangOptions().AppleKext;
+ bool IsAppleKext = Context.getLangOpts().AppleKext;
if (IsAppleKext)
Components.push_back(VTableComponent::MakeVCallOffset(CharUnits::Zero()));
}
@@ -2136,7 +2136,8 @@
uint64_t VTableIndex = I->first;
const std::string &MethodName = I->second;
- Out << llvm::format(" %4"PRIu64" | ", VTableIndex) << MethodName << '\n';
+ Out << llvm::format(" %4" PRIu64 " | ", VTableIndex) << MethodName
+ << '\n';
}
}
Modified: cfe/branches/tooling/lib/Analysis/AnalysisDeclContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Analysis/AnalysisDeclContext.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Analysis/AnalysisDeclContext.cpp (original)
+++ cfe/branches/tooling/lib/Analysis/AnalysisDeclContext.cpp Mon Mar 19 14:02:20 2012
@@ -25,7 +25,7 @@
#include "clang/Analysis/CFGStmtMap.h"
#include "clang/Analysis/Support/BumpVector.h"
#include "llvm/Support/SaveAndRestore.h"
-#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/ErrorHandling.h"
using namespace clang;
@@ -180,7 +180,7 @@
}
void AnalysisDeclContext::dumpCFG(bool ShowColors) {
- getCFG()->dump(getASTContext().getLangOptions(), ShowColors);
+ getCFG()->dump(getASTContext().getLangOpts(), ShowColors);
}
ParentMap &AnalysisDeclContext::getParentMap() {
@@ -335,8 +335,8 @@
class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
BumpVector<const VarDecl*> &BEVals;
BumpVectorContext &BC;
- llvm::DenseMap<const VarDecl*, unsigned> Visited;
- llvm::SmallSet<const DeclContext*, 4> IgnoredContexts;
+ llvm::SmallPtrSet<const VarDecl*, 4> Visited;
+ llvm::SmallPtrSet<const DeclContext*, 4> IgnoredContexts;
public:
FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
BumpVectorContext &bc)
@@ -355,22 +355,12 @@
void VisitDeclRefExpr(DeclRefExpr *DR) {
// Non-local variables are also directly modified.
- if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl()))
+ if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
if (!VD->hasLocalStorage()) {
- unsigned &flag = Visited[VD];
- if (!flag) {
- flag = 1;
+ if (Visited.insert(VD))
BEVals.push_back(VD, BC);
- }
- }
- }
-
- void VisitBlockDeclRefExpr(BlockDeclRefExpr *DR) {
- if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
- unsigned &flag = Visited[VD];
- if (!flag) {
- flag = 1;
- if (IsTrackedDecl(VD))
+ } else if (DR->refersToEnclosingLocal()) {
+ if (Visited.insert(VD) && IsTrackedDecl(VD))
BEVals.push_back(VD, BC);
}
}
Modified: cfe/branches/tooling/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Analysis/CFG.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Analysis/CFG.cpp (original)
+++ cfe/branches/tooling/lib/Analysis/CFG.cpp Mon Mar 19 14:02:20 2012
@@ -1239,7 +1239,7 @@
bool AddEHEdge = false;
// Languages without exceptions are assumed to not throw.
- if (Context->getLangOptions().Exceptions) {
+ if (Context->getLangOpts().Exceptions) {
if (BuildOpts.AddEHEdges)
AddEHEdge = true;
}
@@ -2620,9 +2620,18 @@
CFGBlock *CatchBlock = Block;
if (!CatchBlock)
CatchBlock = createBlock();
+
+ // CXXCatchStmt is more than just a label. They have semantic meaning
+ // as well, as they implicitly "initialize" the catch variable. Add
+ // it to the CFG as a CFGElement so that the control-flow of these
+ // semantics gets captured.
+ appendStmt(CatchBlock, CS);
+ // Also add the CXXCatchStmt as a label, to mirror handling of regular
+ // labels.
CatchBlock->setLabel(CS);
+ // Bail out if the CFG is bad.
if (badCFG)
return 0;
Modified: cfe/branches/tooling/lib/Analysis/CallGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Analysis/CallGraph.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Analysis/CallGraph.cpp (original)
+++ cfe/branches/tooling/lib/Analysis/CallGraph.cpp Mon Mar 19 14:02:20 2012
@@ -14,6 +14,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/StmtVisitor.h"
#include "llvm/Support/GraphWriter.h"
@@ -63,7 +64,7 @@
CallGraphNode *CalleeNode = G->getOrInsertFunction(CalleeDecl);
CallerNode->addCallee(CalleeNode, G);
}
- };
+ }
void VisitChildren(Stmt *S) {
for (Stmt::child_range I = S->children(); I; ++I)
@@ -71,6 +72,35 @@
static_cast<CGBuilder*>(this)->Visit(*I);
}
};
+
+/// A helper class which walks the AST declarations.
+// TODO: We might want to specialize the visitor to shrink the call graph.
+// For example, we might not want to include the inline methods from header
+// files.
+class CGDeclVisitor : public RecursiveASTVisitor<CGDeclVisitor> {
+ CallGraph *CG;
+
+public:
+ CGDeclVisitor(CallGraph * InCG) : CG(InCG) {}
+
+ bool VisitFunctionDecl(FunctionDecl *FD) {
+ // We skip function template definitions, as their semantics is
+ // only determined when they are instantiated.
+ if (includeInGraph(FD))
+ // If this function has external linkage, anything could call it.
+ // Note, we are not precise here. For example, the function could have
+ // its address taken.
+ CG->addToCallGraph(FD, FD->isGlobal());
+ return true;
+ }
+
+ bool VisitObjCMethodDecl(ObjCMethodDecl *MD) {
+ if (includeInGraph(MD))
+ CG->addToCallGraph(MD, true);
+ return true;
+ }
+};
+
} // end anonymous namespace
CallGraph::CallGraph() {
@@ -87,6 +117,7 @@
}
void CallGraph::addToCallGraph(Decl* D, bool IsGlobal) {
+ assert(D);
CallGraphNode *Node = getOrInsertFunction(D);
if (IsGlobal)
@@ -97,42 +128,14 @@
builder.Visit(D->getBody());
}
-void CallGraph::addToCallGraph(DeclContext *DC) {
- for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
- I != E; ++I) {
- Decl *D = *I;
- switch (D->getKind()) {
- case Decl::CXXConstructor:
- case Decl::CXXDestructor:
- case Decl::CXXConversion:
- case Decl::CXXMethod:
- case Decl::Function: {
- FunctionDecl *FD = cast<FunctionDecl>(D);
- // We skip function template definitions, as their semantics is
- // only determined when they are instantiated.
- if (includeInGraph(FD))
- // If this function has external linkage, anything could call it.
- // Note, we are not precise here. For example, the function could have
- // its address taken.
- addToCallGraph(FD, FD->isGlobal());
- break;
- }
-
- case Decl::ObjCCategoryImpl:
- case Decl::ObjCImplementation: {
- ObjCImplDecl *ID = cast<ObjCImplDecl>(D);
- for (ObjCContainerDecl::method_iterator MI = ID->meth_begin(),
- ME = ID->meth_end(); MI != ME; ++MI) {
- if (includeInGraph(*MI))
- addToCallGraph(*MI, true);
- }
- break;
- }
+void CallGraph::addToCallGraph(TranslationUnitDecl *TU) {
+ CGDeclVisitor(this).TraverseDecl(TU);
+}
- default:
- break;
- }
- }
+CallGraphNode *CallGraph::getNode(const Decl *F) const {
+ FunctionMapTy::const_iterator I = FunctionMap.find(F);
+ if (I == FunctionMap.end()) return 0;
+ return I->second;
}
CallGraphNode *CallGraph::getOrInsertFunction(Decl *F) {
@@ -141,7 +144,9 @@
return Node;
Node = new CallGraphNode(F);
- ParentlessNodes.insert(Node);
+ // If not root, add to the parentless list.
+ if (F != 0)
+ ParentlessNodes.insert(Node);
return Node;
}
Modified: cfe/branches/tooling/lib/Analysis/CocoaConventions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Analysis/CocoaConventions.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Analysis/CocoaConventions.cpp (original)
+++ cfe/branches/tooling/lib/Analysis/CocoaConventions.cpp Mon Mar 19 14:02:20 2012
@@ -20,46 +20,6 @@
using namespace clang;
using namespace ento;
-// The "fundamental rule" for naming conventions of methods:
-// (url broken into two lines)
-// http://developer.apple.com/documentation/Cocoa/Conceptual/
-// MemoryMgmt/Tasks/MemoryManagementRules.html
-//
-// "You take ownership of an object if you create it using a method whose name
-// begins with "alloc" or "new" or contains "copy" (for example, alloc,
-// newObject, or mutableCopy), or if you send it a retain message. You are
-// responsible for relinquishing ownership of objects you own using release
-// or autorelease. Any other time you receive an object, you must
-// not release it."
-//
-
-cocoa::NamingConvention cocoa::deriveNamingConvention(Selector S,
- const ObjCMethodDecl *MD) {
- switch (MD && MD->hasAttr<ObjCMethodFamilyAttr>()? MD->getMethodFamily()
- : S.getMethodFamily()) {
- case OMF_None:
- case OMF_autorelease:
- case OMF_dealloc:
- case OMF_finalize:
- case OMF_release:
- case OMF_retain:
- case OMF_retainCount:
- case OMF_self:
- case OMF_performSelector:
- return NoConvention;
-
- case OMF_init:
- return InitRule;
-
- case OMF_alloc:
- case OMF_copy:
- case OMF_mutableCopy:
- case OMF_new:
- return CreateRule;
- }
- llvm_unreachable("unexpected naming convention");
-}
-
bool cocoa::isRefType(QualType RetTy, StringRef Prefix,
StringRef Name) {
// Recursively walk the typedef stack, allowing typedefs of reference types.
Modified: cfe/branches/tooling/lib/Analysis/FormatString.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Analysis/FormatString.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Analysis/FormatString.cpp (original)
+++ cfe/branches/tooling/lib/Analysis/FormatString.cpp Mon Mar 19 14:02:20 2012
@@ -156,6 +156,9 @@
}
if (Amt.getHowSpecified() == OptionalAmount::Constant && *(I++) == '$') {
+ // Warn that positional arguments are non-standard.
+ H.HandlePosition(Start, I - Start);
+
// Special case: '%0$', since this is an easy mistake.
if (Amt.getConstantAmount() == 0) {
H.HandleZeroPosition(Start, I - Start);
@@ -334,7 +337,7 @@
case CPointerTy:
return argTy->isPointerType() || argTy->isObjCObjectPointerType() ||
- argTy->isNullPtrType();
+ argTy->isBlockPointerType() || argTy->isNullPtrType();
case ObjCPointerTy: {
if (argTy->getAs<ObjCObjectPointerType>() ||
Modified: cfe/branches/tooling/lib/Analysis/PseudoConstantAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Analysis/PseudoConstantAnalysis.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Analysis/PseudoConstantAnalysis.cpp (original)
+++ cfe/branches/tooling/lib/Analysis/PseudoConstantAnalysis.cpp Mon Mar 19 14:02:20 2012
@@ -68,8 +68,6 @@
const Decl *PseudoConstantAnalysis::getDecl(const Expr *E) {
if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E))
return DR->getDecl();
- else if (const BlockDeclRefExpr *BDR = dyn_cast<BlockDeclRefExpr>(E))
- return BDR->getDecl();
else
return 0;
}
@@ -198,18 +196,7 @@
break;
}
- // Case 4: Block variable references
- case Stmt::BlockDeclRefExprClass: {
- const BlockDeclRefExpr *BDR = cast<BlockDeclRefExpr>(Head);
- if (const VarDecl *VD = dyn_cast<VarDecl>(BDR->getDecl())) {
- // Add the Decl to the used list
- UsedVars->insert(VD);
- continue;
- }
- break;
- }
-
- // Case 5: Variable references
+ // Case 4: Variable references
case Stmt::DeclRefExprClass: {
const DeclRefExpr *DR = cast<DeclRefExpr>(Head);
if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
@@ -220,7 +207,7 @@
break;
}
- // Case 6: Block expressions
+ // Case 5: Block expressions
case Stmt::BlockExprClass: {
const BlockExpr *B = cast<BlockExpr>(Head);
// Add the body of the block to the list
Modified: cfe/branches/tooling/lib/Analysis/ThreadSafety.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Analysis/ThreadSafety.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Analysis/ThreadSafety.cpp (original)
+++ cfe/branches/tooling/lib/Analysis/ThreadSafety.cpp Mon Mar 19 14:02:20 2012
@@ -1040,7 +1040,7 @@
addLock(Mutex, LockData(ExpLocation, LK));
if (isScopedVar) {
// For scoped lockable vars, map this var to its underlying mutex.
- DeclRefExpr DRE(VD, VD->getType(), VK_LValue, VD->getLocation());
+ DeclRefExpr DRE(VD, false, VD->getType(), VK_LValue, VD->getLocation());
MutexID SMutex(&DRE, 0, 0);
addLock(SMutex, LockData(VD->getLocation(), LK, Mutex));
}
@@ -1656,7 +1656,7 @@
// Create a dummy expression,
VarDecl *VD = const_cast<VarDecl*>(AD->getVarDecl());
- DeclRefExpr DRE(VD, VD->getType(), VK_LValue,
+ DeclRefExpr DRE(VD, false, VD->getType(), VK_LValue,
AD->getTriggerStmt()->getLocEnd());
LocksetBuilder.handleCall(&DRE, DD);
break;
Modified: cfe/branches/tooling/lib/Basic/ConvertUTF.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Basic/ConvertUTF.c?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Basic/ConvertUTF.c (original)
+++ cfe/branches/tooling/lib/Basic/ConvertUTF.c Mon Mar 19 14:02:20 2012
@@ -387,7 +387,7 @@
*/
Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) {
int length = trailingBytesForUTF8[*source]+1;
- if (source+length > sourceEnd) {
+ if (length > sourceEnd - source) {
return false;
}
return isLegalUTF8(source, length);
@@ -395,6 +395,22 @@
/* --------------------------------------------------------------------- */
+/*
+ * Exported function to return whether a UTF-8 string is legal or not.
+ * This is not used here; it's just exported.
+ */
+Boolean isLegalUTF8String(const UTF8 *source, const UTF8 *sourceEnd) {
+ while (source != sourceEnd) {
+ int length = trailingBytesForUTF8[*source] + 1;
+ if (length > sourceEnd - source || !isLegalUTF8(source, length))
+ return false;
+ source += length;
+ }
+ return true;
+}
+
+/* --------------------------------------------------------------------- */
+
ConversionResult ConvertUTF8toUTF16 (
const UTF8** sourceStart, const UTF8* sourceEnd,
UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
@@ -404,7 +420,7 @@
while (source < sourceEnd) {
UTF32 ch = 0;
unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
- if (source + extraBytesToRead >= sourceEnd) {
+ if (extraBytesToRead >= sourceEnd - source) {
result = sourceExhausted; break;
}
/* Do this check whether lenient or strict */
@@ -477,7 +493,7 @@
while (source < sourceEnd) {
UTF32 ch = 0;
unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
- if (source + extraBytesToRead >= sourceEnd) {
+ if (extraBytesToRead >= sourceEnd - source) {
result = sourceExhausted; break;
}
/* Do this check whether lenient or strict */
Modified: cfe/branches/tooling/lib/Basic/Diagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Basic/Diagnostic.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Basic/Diagnostic.cpp (original)
+++ cfe/branches/tooling/lib/Basic/Diagnostic.cpp Mon Mar 19 14:02:20 2012
@@ -357,7 +357,7 @@
NumDiagArgs = 0;
NumDiagRanges = storedDiag.range_size();
- assert(NumDiagRanges < sizeof(DiagRanges)/sizeof(DiagRanges[0]) &&
+ assert(NumDiagRanges < DiagnosticsEngine::MaxRanges &&
"Too many arguments to diagnostic!");
unsigned i = 0;
for (StoredDiagnostic::range_iterator
@@ -365,11 +365,13 @@
RE = storedDiag.range_end(); RI != RE; ++RI)
DiagRanges[i++] = *RI;
- FixItHints.clear();
+ assert(NumDiagRanges < DiagnosticsEngine::MaxFixItHints &&
+ "Too many arguments to diagnostic!");
+ NumDiagFixItHints = 0;
for (StoredDiagnostic::fixit_iterator
FI = storedDiag.fixit_begin(),
FE = storedDiag.fixit_end(); FI != FE; ++FI)
- FixItHints.push_back(*FI);
+ DiagFixItHints[NumDiagFixItHints++] = *FI;
assert(Client && "DiagnosticConsumer not set!");
Level DiagLevel = storedDiag.getLevel();
@@ -383,34 +385,18 @@
CurDiagID = ~0U;
}
-void DiagnosticBuilder::FlushCounts() {
- DiagObj->NumDiagArgs = NumArgs;
- DiagObj->NumDiagRanges = NumRanges;
-}
-
-bool DiagnosticBuilder::Emit() {
- // If DiagObj is null, then its soul was stolen by the copy ctor
- // or the user called Emit().
- if (DiagObj == 0) return false;
-
- // When emitting diagnostics, we set the final argument count into
- // the DiagnosticsEngine object.
- FlushCounts();
-
+bool DiagnosticsEngine::EmitCurrentDiagnostic() {
// Process the diagnostic, sending the accumulated information to the
// DiagnosticConsumer.
- bool Emitted = DiagObj->ProcessDiag();
+ bool Emitted = ProcessDiag();
// Clear out the current diagnostic object.
- unsigned DiagID = DiagObj->CurDiagID;
- DiagObj->Clear();
+ unsigned DiagID = CurDiagID;
+ Clear();
// If there was a delayed diagnostic, emit it now.
- if (DiagObj->DelayedDiagID && DiagObj->DelayedDiagID != DiagID)
- DiagObj->ReportDelayed();
-
- // This diagnostic is dead.
- DiagObj = 0;
+ if (DelayedDiagID && DelayedDiagID != DiagID)
+ ReportDelayed();
return Emitted;
}
Modified: cfe/branches/tooling/lib/Basic/IdentifierTable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Basic/IdentifierTable.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Basic/IdentifierTable.cpp (original)
+++ cfe/branches/tooling/lib/Basic/IdentifierTable.cpp Mon Mar 19 14:02:20 2012
@@ -113,7 +113,7 @@
///
/// The C90/C99/CPP/CPP0x flags are set to 3 if the token is a keyword in a
/// future language standard, set to 2 if the token should be enabled in the
-/// specified langauge, set to 1 if it is an extension in the specified
+/// specified language, set to 1 if it is an extension in the specified
/// language, and set to 0 if disabled in the specified language.
static void AddKeyword(StringRef Keyword,
tok::TokenKind TokenCode, unsigned Flags,
Modified: cfe/branches/tooling/lib/Basic/Targets.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Basic/Targets.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Basic/Targets.cpp (original)
+++ cfe/branches/tooling/lib/Basic/Targets.cpp Mon Mar 19 14:02:20 2012
@@ -871,6 +871,11 @@
default:
break;
}
+
+ if (getTriple().getOS() == llvm::Triple::FreeBSD) {
+ LongDoubleWidth = LongDoubleAlign = 64;
+ LongDoubleFormat = &llvm::APFloat::IEEEdouble;
+ }
}
virtual const char *getVAListDeclaration() const {
@@ -896,6 +901,11 @@
Int64Type = SignedLong;
DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64";
+
+ if (getTriple().getOS() == llvm::Triple::FreeBSD) {
+ LongDoubleWidth = LongDoubleAlign = 64;
+ LongDoubleFormat = &llvm::APFloat::IEEEdouble;
+ }
}
virtual const char *getVAListDeclaration() const {
return "typedef char* __builtin_va_list;";
@@ -1884,8 +1894,10 @@
MacroBuilder &Builder) const {
// Target identification.
if (PointerWidth == 64) {
- Builder.defineMacro("_LP64");
- Builder.defineMacro("__LP64__");
+ if (getLongWidth() == 64) {
+ Builder.defineMacro("_LP64");
+ Builder.defineMacro("__LP64__");
+ }
Builder.defineMacro("__amd64__");
Builder.defineMacro("__amd64");
Builder.defineMacro("__x86_64");
@@ -2653,6 +2665,12 @@
// ARM has atomics up to 8 bytes
// FIXME: Set MaxAtomicInlineWidth if we have the feature v6e
MaxAtomicPromoteWidth = 64;
+
+ // Do force alignment of members that follow zero length bitfields. If
+ // the alignment of the zero-length bitfield is greater than the member
+ // that follows it, `bar', `bar' will be aligned as the type of the
+ // zero length bitfield.
+ UseZeroLengthBitfieldAlignment = true;
}
virtual const char *getABI() const { return ABI.c_str(); }
virtual bool setABI(const std::string &Name) {
@@ -2673,12 +2691,6 @@
// structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
UseBitFieldTypeAlignment = false;
- /// Do force alignment of members that follow zero length bitfields. If
- /// the alignment of the zero-length bitfield is greater than the member
- /// that follows it, `bar', `bar' will be aligned as the type of the
- /// zero length bitfield.
- UseZeroLengthBitfieldAlignment = true;
-
/// gcc forces the alignment to 4 bytes, regardless of the type of the
/// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in
/// gcc.
Modified: cfe/branches/tooling/lib/CodeGen/CGBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGBlocks.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGBlocks.cpp Mon Mar 19 14:02:20 2012
@@ -92,7 +92,7 @@
CGM.GetAddrOfConstantCString(typeAtEncoding), i8p));
// GC layout.
- if (C.getLangOptions().ObjC1)
+ if (C.getLangOpts().ObjC1)
elements.push_back(CGM.getObjCRuntime().BuildGCBlockLayout(CGM, blockInfo));
else
elements.push_back(llvm::Constant::getNullValue(i8p));
@@ -227,7 +227,7 @@
// Except that any class member declared mutable can be
// modified, any attempt to modify a const object during its
// lifetime results in undefined behavior.
- if (CGM.getLangOptions().CPlusPlus && !isSafeForCXXConstantCapture(type))
+ if (CGM.getLangOpts().CPlusPlus && !isSafeForCXXConstantCapture(type))
return 0;
// If the variable doesn't have any initializer (shouldn't this be
@@ -374,7 +374,7 @@
info.HasCXXObject = true;
// And so do types with destructors.
- } else if (CGM.getLangOptions().CPlusPlus) {
+ } else if (CGM.getLangOpts().CPlusPlus) {
if (const CXXRecordDecl *record =
variable->getType()->getAsCXXRecordDecl()) {
if (!record->hasTrivialDestructor()) {
@@ -753,16 +753,12 @@
// We use one of these or the other depending on whether the
// reference is nested.
- DeclRefExpr notNested(const_cast<VarDecl*>(variable), type, VK_LValue,
- SourceLocation());
- BlockDeclRefExpr nested(const_cast<VarDecl*>(variable), type,
- VK_LValue, SourceLocation(), /*byref*/ false);
-
- Expr *declRef =
- (ci->isNested() ? static_cast<Expr*>(&nested) : ¬Nested);
+ DeclRefExpr declRef(const_cast<VarDecl*>(variable),
+ /*refersToEnclosing*/ ci->isNested(), type,
+ VK_LValue, SourceLocation());
ImplicitCastExpr l2r(ImplicitCastExpr::OnStack, type, CK_LValueToRValue,
- declRef, VK_RValue);
+ &declRef, VK_RValue);
EmitExprAsInit(&l2r, &blockFieldPseudoVar,
MakeAddrLValue(blockField, type,
getContext().getDeclAlign(variable)),
@@ -1107,7 +1103,7 @@
LocalDeclMap[variable] = alloca;
}
- // Save a spot to insert the debug information for all the BlockDeclRefDecls.
+ // Save a spot to insert the debug information for all the DeclRefExprs.
llvm::BasicBlock *entry = Builder.GetInsertBlock();
llvm::BasicBlock::iterator entry_ptr = Builder.GetInsertPoint();
--entry_ptr;
@@ -1124,7 +1120,7 @@
++entry_ptr;
Builder.SetInsertPoint(entry, entry_ptr);
- // Emit debug information for all the BlockDeclRefDecls.
+ // Emit debug information for all the DeclRefExprs.
// FIXME: also for 'this'
if (CGDebugInfo *DI = getDebugInfo()) {
for (BlockDecl::capture_const_iterator ci = blockDecl->capture_begin(),
@@ -1255,7 +1251,7 @@
flags = BLOCK_FIELD_IS_BLOCK;
// Special rules for ARC captures:
- if (getLangOptions().ObjCAutoRefCount) {
+ if (getLangOpts().ObjCAutoRefCount) {
Qualifiers qs = type.getQualifiers();
// Don't generate special copy logic for a captured object
@@ -1367,7 +1363,7 @@
flags = BLOCK_FIELD_IS_BLOCK;
// Special rules for ARC captures.
- if (getLangOptions().ObjCAutoRefCount) {
+ if (getLangOpts().ObjCAutoRefCount) {
Qualifiers qs = type.getQualifiers();
// Don't generate special dispose logic for a captured object
@@ -1748,7 +1744,7 @@
// If we have lifetime, that dominates.
if (Qualifiers::ObjCLifetime lifetime = qs.getObjCLifetime()) {
- assert(getLangOptions().ObjCAutoRefCount);
+ assert(getLangOpts().ObjCAutoRefCount);
switch (lifetime) {
case Qualifiers::OCL_None: llvm_unreachable("impossible");
@@ -1983,7 +1979,7 @@
/// to be done externally.
void CodeGenFunction::enterByrefCleanup(const AutoVarEmission &emission) {
// We don't enter this cleanup if we're in pure-GC mode.
- if (CGM.getLangOptions().getGC() == LangOptions::GCOnly)
+ if (CGM.getLangOpts().getGC() == LangOptions::GCOnly)
return;
EHStack.pushCleanup<CallBlockRelease>(NormalAndEHCleanup, emission.Address);
@@ -1992,7 +1988,7 @@
/// Adjust the declaration of something from the blocks API.
static void configureBlocksRuntimeObject(CodeGenModule &CGM,
llvm::Constant *C) {
- if (!CGM.getLangOptions().BlocksRuntimeOptional) return;
+ if (!CGM.getLangOpts().BlocksRuntimeOptional) return;
llvm::GlobalValue *GV = cast<llvm::GlobalValue>(C->stripPointerCasts());
if (GV->isDeclaration() &&
Modified: cfe/branches/tooling/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGBuiltin.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGBuiltin.cpp Mon Mar 19 14:02:20 2012
@@ -942,12 +942,13 @@
case Builtin::BI__sync_lock_release_8:
case Builtin::BI__sync_lock_release_16: {
Value *Ptr = EmitScalarExpr(E->getArg(0));
- llvm::Type *ElLLVMTy =
- cast<llvm::PointerType>(Ptr->getType())->getElementType();
- llvm::StoreInst *Store =
- Builder.CreateStore(llvm::Constant::getNullValue(ElLLVMTy), Ptr);
QualType ElTy = E->getArg(0)->getType()->getPointeeType();
CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy);
+ llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(),
+ StoreSize.getQuantity() * 8);
+ Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo());
+ llvm::StoreInst *Store =
+ Builder.CreateStore(llvm::Constant::getNullValue(ITy), Ptr);
Store->setAlignment(StoreSize.getQuantity());
Store->setAtomic(llvm::Release);
return RValue::get(0);
@@ -1630,10 +1631,10 @@
Int = Intrinsic::arm_neon_vld2;
break;
case ARM::BI__builtin_neon_vld3_dup_v:
- Int = Intrinsic::arm_neon_vld2;
+ Int = Intrinsic::arm_neon_vld3;
break;
case ARM::BI__builtin_neon_vld4_dup_v:
- Int = Intrinsic::arm_neon_vld2;
+ Int = Intrinsic::arm_neon_vld4;
break;
default: llvm_unreachable("unknown vld_dup intrinsic?");
}
@@ -1649,10 +1650,10 @@
Int = Intrinsic::arm_neon_vld2lane;
break;
case ARM::BI__builtin_neon_vld3_dup_v:
- Int = Intrinsic::arm_neon_vld2lane;
+ Int = Intrinsic::arm_neon_vld3lane;
break;
case ARM::BI__builtin_neon_vld4_dup_v:
- Int = Intrinsic::arm_neon_vld2lane;
+ Int = Intrinsic::arm_neon_vld4lane;
break;
default: llvm_unreachable("unknown vld_dup intrinsic?");
}
Modified: cfe/branches/tooling/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGCall.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGCall.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGCall.cpp Mon Mar 19 14:02:20 2012
@@ -254,7 +254,7 @@
FunctionType::ExtInfo einfo;
einfo = einfo.withCallingConv(getCallingConventionForDecl(MD));
- if (getContext().getLangOptions().ObjCAutoRefCount &&
+ if (getContext().getLangOpts().ObjCAutoRefCount &&
MD->hasAttr<NSReturnsRetainedAttr>())
einfo = einfo.withProducesResult(true);
@@ -623,7 +623,9 @@
SI->setAlignment(1);
}
} else {
- CGF.Builder.CreateStore(Val, DestPtr, DestIsVolatile);
+ llvm::StoreInst *SI = CGF.Builder.CreateStore(Val, DestPtr, DestIsVolatile);
+ if (LowAlignment)
+ SI->setAlignment(1);
}
}
@@ -1467,7 +1469,7 @@
// In ARC, end functions that return a retainable type with a call
// to objc_autoreleaseReturnValue.
if (AutoreleaseResult) {
- assert(getLangOptions().ObjCAutoRefCount &&
+ assert(getLangOpts().ObjCAutoRefCount &&
!FI.isReturnsRetained() &&
RetTy->isObjCRetainableType());
RV = emitAutoreleaseOfResult(*this, RV);
@@ -1662,7 +1664,7 @@
QualType type) {
if (const ObjCIndirectCopyRestoreExpr *CRE
= dyn_cast<ObjCIndirectCopyRestoreExpr>(E)) {
- assert(getContext().getLangOptions().ObjCAutoRefCount);
+ assert(getContext().getLangOpts().ObjCAutoRefCount);
assert(getContext().hasSameType(E->getType(), type));
return emitWritebackArg(*this, args, CRE);
}
@@ -1717,7 +1719,7 @@
// In ObjC ARC mode with no ObjC ARC exception safety, tell the ARC
// optimizer it can aggressively ignore unwind edges.
- if (CGM.getLangOptions().ObjCAutoRefCount)
+ if (CGM.getLangOpts().ObjCAutoRefCount)
AddObjCARCExceptionMetadata(Inst);
return Inst;
@@ -2031,7 +2033,7 @@
// In ObjC ARC mode with no ObjC ARC exception safety, tell the ARC
// optimizer it can aggressively ignore unwind edges.
- if (CGM.getLangOptions().ObjCAutoRefCount)
+ if (CGM.getLangOpts().ObjCAutoRefCount)
AddObjCARCExceptionMetadata(CS.getInstruction());
// If the call doesn't return, finish the basic block and clear the
Modified: cfe/branches/tooling/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGClass.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGClass.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGClass.cpp Mon Mar 19 14:02:20 2012
@@ -405,7 +405,7 @@
CGF.EmitAggExpr(BaseInit->getInit(), AggSlot);
- if (CGF.CGM.getLangOptions().Exceptions &&
+ if (CGF.CGM.getLangOpts().Exceptions &&
!BaseClassDecl->hasTrivialDestructor())
CGF.EHStack.pushCleanup<CallBaseDtor>(EHCleanup, BaseClassDecl,
isBaseVirtual);
@@ -642,7 +642,7 @@
EmitAggMemberInitializer(*this, LHS, Init, ArrayIndexVar, FieldType,
ArrayIndexes, 0);
- if (!CGM.getLangOptions().Exceptions)
+ if (!CGM.getLangOpts().Exceptions)
return;
// FIXME: If we have an array of classes w/ non-trivial destructors,
@@ -935,7 +935,7 @@
}
// -fapple-kext must inline any call to this dtor into
// the caller's body.
- if (getContext().getLangOptions().AppleKext)
+ if (getContext().getLangOpts().AppleKext)
CurFn->addFnAttr(llvm::Attribute::AlwaysInline);
break;
}
@@ -1172,7 +1172,7 @@
// Evaluate the constructor and its arguments in a regular
// partial-destroy cleanup.
- if (getLangOptions().Exceptions &&
+ if (getLangOpts().Exceptions &&
!ctor->getParent()->hasTrivialDestructor()) {
Destroyer *destroyer = destroyCXXObject;
pushRegularPartialArrayCleanup(arrayBegin, cur, type, *destroyer);
@@ -1376,7 +1376,7 @@
EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot);
const CXXRecordDecl *ClassDecl = Ctor->getParent();
- if (CGM.getLangOptions().Exceptions && !ClassDecl->hasTrivialDestructor()) {
+ if (CGM.getLangOpts().Exceptions && !ClassDecl->hasTrivialDestructor()) {
CXXDtorType Type =
CurGD.getCtorType() == Ctor_Complete ? Dtor_Complete : Dtor_Base;
@@ -1393,7 +1393,7 @@
llvm::Value *VTT = GetVTTParameter(*this, GlobalDecl(DD, Type),
ForVirtualBase);
llvm::Value *Callee = 0;
- if (getContext().getLangOptions().AppleKext)
+ if (getContext().getLangOpts().AppleKext)
Callee = BuildAppleKextVirtualDestructorCall(DD, Type,
DD->getParent());
@@ -1711,7 +1711,7 @@
// When building with -fapple-kext, all calls must go through the vtable since
// the kernel linker can do runtime patching of vtables.
- if (Context.getLangOptions().AppleKext)
+ if (Context.getLangOpts().AppleKext)
return true;
return !canDevirtualizeMemberFunctionCall(CE->getArg(0), MD);
Modified: cfe/branches/tooling/lib/CodeGen/CGCleanup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGCleanup.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGCleanup.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGCleanup.cpp Mon Mar 19 14:02:20 2012
@@ -504,7 +504,7 @@
llvm::SwitchInst *si = cast<llvm::SwitchInst>(use.getUser());
if (si->getNumCases() == 1 && si->getDefaultDest() == unreachableBB) {
// Replace the switch with a branch.
- llvm::BranchInst::Create(si->caseBegin().getCaseSuccessor(), si);
+ llvm::BranchInst::Create(si->case_begin().getCaseSuccessor(), si);
// The switch operand is a load from the cleanup-dest alloca.
llvm::LoadInst *condition = cast<llvm::LoadInst>(si->getCondition());
Modified: cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp Mon Mar 19 14:02:20 2012
@@ -117,12 +117,25 @@
StringRef CGDebugInfo::getFunctionName(const FunctionDecl *FD) {
assert (FD && "Invalid FunctionDecl!");
IdentifierInfo *FII = FD->getIdentifier();
- if (FII)
+ FunctionTemplateSpecializationInfo *Info
+ = FD->getTemplateSpecializationInfo();
+ if (!Info && FII)
return FII->getName();
// Otherwise construct human readable name for debug info.
std::string NS = FD->getNameAsString();
+ // Add any template specialization args.
+ if (Info) {
+ const TemplateArgumentList *TArgs = Info->TemplateArguments;
+ const TemplateArgument *Args = TArgs->data();
+ unsigned NumArgs = TArgs->size();
+ PrintingPolicy Policy(CGM.getLangOpts());
+ NS += TemplateSpecializationType::PrintTemplateArgumentList(Args,
+ NumArgs,
+ Policy);
+ }
+
// Copy this name on the side and use its reference.
char *StrPtr = DebugInfoNames.Allocate<char>(NS.length());
memcpy(StrPtr, NS.data(), NS.length());
@@ -183,7 +196,7 @@
NumArgs = TemplateArgs.size();
}
Buffer = RD->getIdentifier()->getNameStart();
- PrintingPolicy Policy(CGM.getLangOptions());
+ PrintingPolicy Policy(CGM.getLangOpts());
Buffer += TemplateSpecializationType::PrintTemplateArgumentList(Args,
NumArgs,
Policy);
@@ -288,7 +301,7 @@
StringRef Filename(FilenamePtr, MainFileName.length());
unsigned LangTag;
- const LangOptions &LO = CGM.getLangOptions();
+ const LangOptions &LO = CGM.getLangOpts();
if (LO.CPlusPlus) {
if (LO.ObjC1)
LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
@@ -332,7 +345,7 @@
llvm_unreachable("Unexpected builtin type");
case BuiltinType::NullPtr:
return DBuilder.
- createNullPtrType(BT->getName(CGM.getContext().getLangOptions()));
+ createNullPtrType(BT->getName(CGM.getContext().getLangOpts()));
case BuiltinType::Void:
return llvm::DIType();
case BuiltinType::ObjCClass:
@@ -403,7 +416,7 @@
case BuiltinType::ULong: BTName = "long unsigned int"; break;
case BuiltinType::ULongLong: BTName = "long long unsigned int"; break;
default:
- BTName = BT->getName(CGM.getContext().getLangOptions());
+ BTName = BT->getName(CGM.getContext().getLangOpts());
break;
}
// Bit size, align and offset of the type.
@@ -831,7 +844,7 @@
= getOrCreateType(QualType(Method->getType()->getAs<FunctionProtoType>(),
0),
Unit);
-
+
// Add "this" pointer.
llvm::DIArray Args = llvm::DICompositeType(FnTy).getTypeArray();
assert (Args.getNumElements() && "Invalid number of arguments!");
@@ -946,14 +959,16 @@
}
if (Method->hasPrototype())
Flags |= llvm::DIDescriptor::FlagPrototyped;
-
+
+ llvm::DIArray TParamsArray = CollectFunctionTemplateParams(Method, Unit);
llvm::DISubprogram SP =
DBuilder.createMethod(RecordTy, MethodName, MethodLinkageName,
MethodDefUnit, MethodLine,
MethodTy, /*isLocalToUnit=*/false,
/* isDefinition=*/ false,
Virtuality, VIndex, ContainingType,
- Flags, CGM.getLangOptions().Optimize);
+ Flags, CGM.getLangOpts().Optimize, NULL,
+ TParamsArray);
SPCache[Method->getCanonicalDecl()] = llvm::WeakVH(SP);
@@ -967,14 +982,25 @@
CollectCXXMemberFunctions(const CXXRecordDecl *RD, llvm::DIFile Unit,
SmallVectorImpl<llvm::Value *> &EltTys,
llvm::DIType RecordTy) {
- for(CXXRecordDecl::method_iterator I = RD->method_begin(),
- E = RD->method_end(); I != E; ++I) {
- const CXXMethodDecl *Method = *I;
-
- if (Method->isImplicit() && !Method->isUsed())
+
+ // Since we want more than just the individual member decls if we
+ // have templated functions iterate over every declaration to gather
+ // the functions.
+ for(DeclContext::decl_iterator I = RD->decls_begin(),
+ E = RD->decls_end(); I != E; ++I) {
+ Decl *D = *I;
+ if (D->isImplicit() && !D->isUsed())
continue;
- EltTys.push_back(CreateCXXMemberFunction(Method, Unit, RecordTy));
+ if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D))
+ EltTys.push_back(CreateCXXMemberFunction(Method, Unit, RecordTy));
+ else if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
+ for (FunctionTemplateDecl::spec_iterator SI = FTD->spec_begin(),
+ SE = FTD->spec_end(); SI != SE; ++SI) {
+ FunctionDecl *FD = *SI;
+ if (CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(FD))
+ EltTys.push_back(CreateCXXMemberFunction(M, Unit, RecordTy));
+ }
}
}
@@ -1345,7 +1371,7 @@
// the non-fragile abi and the debugger should ignore the value anyways.
// Call it the FieldNo+1 due to how debuggers use the information,
// e.g. negating the value when it needs a lookup in the dynamic table.
- uint64_t FieldOffset = CGM.getLangOptions().ObjCNonFragileABI ? FieldNo+1
+ uint64_t FieldOffset = CGM.getLangOpts().ObjCNonFragileABI ? FieldNo+1
: RL.getFieldOffset(FieldNo);
unsigned Flags = 0;
@@ -1996,7 +2022,7 @@
DBuilder.createFunction(FDContext, Name, LinkageName, Unit,
LineNo, getOrCreateFunctionType(D, FnType, Unit),
Fn->hasInternalLinkage(), true/*definition*/,
- Flags, CGM.getLangOptions().Optimize, Fn,
+ Flags, CGM.getLangOpts().Optimize, Fn,
TParamsArray, SPDecl);
// Push function on region stack.
@@ -2227,7 +2253,7 @@
llvm::DIVariable D =
DBuilder.createLocalVariable(Tag, llvm::DIDescriptor(Scope),
Name, Unit, Line, Ty,
- CGM.getLangOptions().Optimize, Flags, ArgNo);
+ CGM.getLangOpts().Optimize, Flags, ArgNo);
// Insert an llvm.dbg.declare into the current block.
llvm::Instruction *Call =
@@ -2256,7 +2282,7 @@
llvm::DIVariable D =
DBuilder.createLocalVariable(Tag, llvm::DIDescriptor(Scope),
FieldName, Unit, Line, FieldTy,
- CGM.getLangOptions().Optimize, Flags,
+ CGM.getLangOpts().Optimize, Flags,
ArgNo);
// Insert an llvm.dbg.declare into the current block.
@@ -2484,7 +2510,7 @@
DBuilder.createLocalVariable(llvm::dwarf::DW_TAG_arg_variable,
llvm::DIDescriptor(scope),
name, tunit, line, type,
- CGM.getLangOptions().Optimize, flags,
+ CGM.getLangOpts().Optimize, flags,
cast<llvm::Argument>(addr)->getArgNo() + 1);
// Insert an llvm.dbg.value into the current block.
Modified: cfe/branches/tooling/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGDecl.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGDecl.cpp Mon Mar 19 14:02:20 2012
@@ -121,7 +121,7 @@
// uniqued. We can't do this in C, though, because there's no
// standard way to agree on which variables are the same (i.e.
// there's no mangling).
- if (getContext().getLangOptions().CPlusPlus)
+ if (getContext().getLangOpts().CPlusPlus)
if (llvm::GlobalValue::isWeakForLinker(CurFn->getLinkage()))
Linkage = CurFn->getLinkage();
@@ -141,7 +141,7 @@
static std::string GetStaticDeclName(CodeGenFunction &CGF, const VarDecl &D,
const char *Separator) {
CodeGenModule &CGM = CGF.CGM;
- if (CGF.getContext().getLangOptions().CPlusPlus) {
+ if (CGF.getContext().getLangOpts().CPlusPlus) {
StringRef Name = CGM.getMangledName(&D);
return Name.str();
}
@@ -216,7 +216,7 @@
// If constant emission failed, then this should be a C++ static
// initializer.
if (!Init) {
- if (!getContext().getLangOptions().CPlusPlus)
+ if (!getContext().getLangOpts().CPlusPlus)
CGM.ErrorUnsupported(D.getInit(), "constant l-value expression");
else if (Builder.GetInsertBlock()) {
// Since we have a static initializer, this global variable can't
@@ -312,7 +312,9 @@
llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(D.getType());
llvm::Type *LPtrTy =
LTy->getPointerTo(CGM.getContext().getTargetAddressSpace(D.getType()));
- DMEntry = llvm::ConstantExpr::getBitCast(GV, LPtrTy);
+ llvm::Constant *CastedVal = llvm::ConstantExpr::getBitCast(GV, LPtrTy);
+ DMEntry = CastedVal;
+ CGM.setStaticLocalDeclAddress(&D, CastedVal);
// Emit global variable debug descriptor for static vars.
CGDebugInfo *DI = getDebugInfo();
@@ -392,8 +394,8 @@
void Emit(CodeGenFunction &CGF, Flags flags) {
// Compute the address of the local variable, in case it's a
// byref or something.
- DeclRefExpr DRE(const_cast<VarDecl*>(&Var), Var.getType(), VK_LValue,
- SourceLocation());
+ DeclRefExpr DRE(const_cast<VarDecl*>(&Var), false,
+ Var.getType(), VK_LValue, SourceLocation());
llvm::Value *value = CGF.EmitLoadOfScalar(CGF.EmitDeclRefLValue(&DRE));
CGF.EmitExtendGCLifetime(value);
}
@@ -409,8 +411,8 @@
: CleanupFn(CleanupFn), FnInfo(*Info), Var(*Var) {}
void Emit(CodeGenFunction &CGF, Flags flags) {
- DeclRefExpr DRE(const_cast<VarDecl*>(&Var), Var.getType(), VK_LValue,
- SourceLocation());
+ DeclRefExpr DRE(const_cast<VarDecl*>(&Var), false,
+ Var.getType(), VK_LValue, SourceLocation());
// Compute the address of the local variable, in case it's a byref
// or something.
llvm::Value *Addr = CGF.EmitDeclRefLValue(&DRE).getAddress();
@@ -768,7 +770,7 @@
llvm::Value *DeclPtr;
if (Ty->isConstantSizeType()) {
if (!Target.useGlobalsForAutomaticVariables()) {
- bool NRVO = getContext().getLangOptions().ElideConstructors &&
+ bool NRVO = getContext().getLangOpts().ElideConstructors &&
D.isNRVOVariable();
// If this value is a POD array or struct with a statically
@@ -1168,7 +1170,7 @@
emitAutoVarTypeCleanup(emission, dtorKind);
// In GC mode, honor objc_precise_lifetime.
- if (getLangOptions().getGC() != LangOptions::NonGC &&
+ if (getLangOpts().getGC() != LangOptions::NonGC &&
D.hasAttr<ObjCPreciseLifetimeAttr>()) {
EHStack.pushCleanup<ExtendGCLifetime>(NormalCleanup, &D);
}
Modified: cfe/branches/tooling/lib/CodeGen/CGDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGDeclCXX.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGDeclCXX.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGDeclCXX.cpp Mon Mar 19 14:02:20 2012
@@ -199,14 +199,14 @@
llvm::Function *Fn =
llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
Name, &CGM.getModule());
- if (!CGM.getContext().getLangOptions().AppleKext) {
+ if (!CGM.getContext().getLangOpts().AppleKext) {
// Set the section if needed.
if (const char *Section =
CGM.getContext().getTargetInfo().getStaticInitSectionSpecifier())
Fn->setSection(Section);
}
- if (!CGM.getLangOptions().Exceptions)
+ if (!CGM.getLangOpts().Exceptions)
Fn->setDoesNotThrow();
return Fn;
@@ -327,7 +327,7 @@
// When building in Objective-C++ ARC mode, create an autorelease pool
// around the global initializers.
- if (getLangOptions().ObjCAutoRefCount && getLangOptions().CPlusPlus) {
+ if (getLangOpts().ObjCAutoRefCount && getLangOpts().CPlusPlus) {
llvm::Value *token = EmitObjCAutoreleasePoolPush();
EmitObjCAutoreleasePoolCleanup(token);
}
Modified: cfe/branches/tooling/lib/CodeGen/CGException.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGException.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGException.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGException.cpp Mon Mar 19 14:02:20 2012
@@ -100,7 +100,7 @@
llvm::FunctionType *FTy =
llvm::FunctionType::get(VoidTy, Int8PtrTy, /*IsVarArgs=*/false);
- if (CGM.getLangOptions().SjLjExceptions)
+ if (CGM.getLangOpts().SjLjExceptions)
return CGM.CreateRuntimeFunction(FTy, "_Unwind_SjLj_Resume");
return CGM.CreateRuntimeFunction(FTy, "_Unwind_Resume");
}
@@ -109,7 +109,7 @@
llvm::FunctionType *FTy =
llvm::FunctionType::get(VoidTy, Int8PtrTy, /*IsVarArgs=*/false);
- if (CGM.getLangOptions().SjLjExceptions)
+ if (CGM.getLangOpts().SjLjExceptions)
return CGM.CreateRuntimeFunction(FTy, "_Unwind_SjLj_Resume_or_Rethrow");
return CGM.CreateRuntimeFunction(FTy, "_Unwind_Resume_or_Rethrow");
}
@@ -123,9 +123,9 @@
StringRef name;
// In C++, use std::terminate().
- if (CGF.getLangOptions().CPlusPlus)
+ if (CGF.getLangOpts().CPlusPlus)
name = "_ZSt9terminatev"; // FIXME: mangling!
- else if (CGF.getLangOptions().ObjC1 &&
+ else if (CGF.getLangOpts().ObjC1 &&
CGF.CGM.getCodeGenOpts().ObjCRuntimeHasTerminate)
name = "objc_terminate";
else
@@ -300,11 +300,11 @@
return;
// If we're not in ObjC++ -fexceptions, there's nothing to do.
- if (!Features.CPlusPlus || !Features.ObjC1 || !Features.Exceptions)
+ if (!LangOpts.CPlusPlus || !LangOpts.ObjC1 || !LangOpts.Exceptions)
return;
- const EHPersonality &ObjCXX = EHPersonality::get(Features);
- const EHPersonality &CXX = getCXXPersonality(Features);
+ const EHPersonality &ObjCXX = EHPersonality::get(LangOpts);
+ const EHPersonality &CXX = getCXXPersonality(LangOpts);
if (&ObjCXX == &CXX)
return;
@@ -470,7 +470,7 @@
}
void CodeGenFunction::EmitStartEHSpec(const Decl *D) {
- if (!CGM.getLangOptions().CXXExceptions)
+ if (!CGM.getLangOpts().CXXExceptions)
return;
const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
@@ -538,7 +538,7 @@
}
void CodeGenFunction::EmitEndEHSpec(const Decl *D) {
- if (!CGM.getLangOptions().CXXExceptions)
+ if (!CGM.getLangOpts().CXXExceptions)
return;
const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
@@ -661,7 +661,7 @@
assert(EHStack.requiresLandingPad());
assert(!EHStack.empty());
- if (!CGM.getLangOptions().Exceptions)
+ if (!CGM.getLangOpts().Exceptions)
return 0;
// Check the innermost scope for a cached landing pad. If this is
@@ -751,7 +751,7 @@
// Save the current IR generation state.
CGBuilderTy::InsertPoint savedIP = Builder.saveAndClearIP();
- const EHPersonality &personality = EHPersonality::get(getLangOptions());
+ const EHPersonality &personality = EHPersonality::get(getLangOpts());
// Create and configure the landing pad.
llvm::BasicBlock *lpad = createBasicBlock("lpad");
@@ -1494,7 +1494,7 @@
Builder.SetInsertPoint(TerminateLandingPad);
// Tell the backend that this is a landing pad.
- const EHPersonality &Personality = EHPersonality::get(CGM.getLangOptions());
+ const EHPersonality &Personality = EHPersonality::get(CGM.getLangOpts());
llvm::LandingPadInst *LPadInst =
Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty, NULL),
getOpaquePersonalityFn(CGM, Personality), 0);
@@ -1541,7 +1541,7 @@
EHResumeBlock = createBasicBlock("eh.resume");
Builder.SetInsertPoint(EHResumeBlock);
- const EHPersonality &Personality = EHPersonality::get(CGM.getLangOptions());
+ const EHPersonality &Personality = EHPersonality::get(CGM.getLangOpts());
// This can always be a call because we necessarily didn't find
// anything on the EH stack which needs our help.
Modified: cfe/branches/tooling/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExpr.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExpr.cpp Mon Mar 19 14:02:20 2012
@@ -225,7 +225,7 @@
// Objective-C++ ARC:
// If we are binding a reference to a temporary that has ownership, we
// need to perform retain/release operations on the temporary.
- if (CGF.getContext().getLangOptions().ObjCAutoRefCount &&
+ if (CGF.getContext().getLangOpts().ObjCAutoRefCount &&
E->getType()->isObjCLifetimeType() &&
(E->getType().getObjCLifetime() == Qualifiers::OCL_Strong ||
E->getType().getObjCLifetime() == Qualifiers::OCL_Weak ||
@@ -679,9 +679,6 @@
"Only single-element init list can be lvalue.");
return EmitLValue(cast<InitListExpr>(E)->getInit(0));
- case Expr::BlockDeclRefExprClass:
- return EmitBlockDeclRefLValue(cast<BlockDeclRefExpr>(E));
-
case Expr::CXXTemporaryObjectExprClass:
case Expr::CXXConstructExprClass:
return EmitCXXConstructLValue(cast<CXXConstructExpr>(E));
@@ -745,6 +742,118 @@
}
}
+/// Given an object of the given canonical type, can we safely copy a
+/// value out of it based on its initializer?
+static bool isConstantEmittableObjectType(QualType type) {
+ assert(type.isCanonical());
+ assert(!type->isReferenceType());
+
+ // Must be const-qualified but non-volatile.
+ Qualifiers qs = type.getLocalQualifiers();
+ if (!qs.hasConst() || qs.hasVolatile()) return false;
+
+ // Otherwise, all object types satisfy this except C++ classes with
+ // mutable subobjects or non-trivial copy/destroy behavior.
+ if (const RecordType *RT = dyn_cast<RecordType>(type))
+ if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
+ if (RD->hasMutableFields() || !RD->isTrivial())
+ return false;
+
+ return true;
+}
+
+/// Can we constant-emit a load of a reference to a variable of the
+/// given type? This is different from predicates like
+/// Decl::isUsableInConstantExpressions because we do want it to apply
+/// in situations that don't necessarily satisfy the language's rules
+/// for this (e.g. C++'s ODR-use rules). For example, we want to able
+/// to do this with const float variables even if those variables
+/// aren't marked 'constexpr'.
+enum ConstantEmissionKind {
+ CEK_None,
+ CEK_AsReferenceOnly,
+ CEK_AsValueOrReference,
+ CEK_AsValueOnly
+};
+static ConstantEmissionKind checkVarTypeForConstantEmission(QualType type) {
+ type = type.getCanonicalType();
+ if (const ReferenceType *ref = dyn_cast<ReferenceType>(type)) {
+ if (isConstantEmittableObjectType(ref->getPointeeType()))
+ return CEK_AsValueOrReference;
+ return CEK_AsReferenceOnly;
+ }
+ if (isConstantEmittableObjectType(type))
+ return CEK_AsValueOnly;
+ return CEK_None;
+}
+
+/// Try to emit a reference to the given value without producing it as
+/// an l-value. This is actually more than an optimization: we can't
+/// produce an l-value for variables that we never actually captured
+/// in a block or lambda, which means const int variables or constexpr
+/// literals or similar.
+CodeGenFunction::ConstantEmission
+CodeGenFunction::tryEmitAsConstant(DeclRefExpr *refExpr) {
+ ValueDecl *value = refExpr->getDecl();
+
+ // The value needs to be an enum constant or a constant variable.
+ ConstantEmissionKind CEK;
+ if (isa<ParmVarDecl>(value)) {
+ CEK = CEK_None;
+ } else if (VarDecl *var = dyn_cast<VarDecl>(value)) {
+ CEK = checkVarTypeForConstantEmission(var->getType());
+ } else if (isa<EnumConstantDecl>(value)) {
+ CEK = CEK_AsValueOnly;
+ } else {
+ CEK = CEK_None;
+ }
+ if (CEK == CEK_None) return ConstantEmission();
+
+ Expr::EvalResult result;
+ bool resultIsReference;
+ QualType resultType;
+
+ // It's best to evaluate all the way as an r-value if that's permitted.
+ if (CEK != CEK_AsReferenceOnly &&
+ refExpr->EvaluateAsRValue(result, getContext())) {
+ resultIsReference = false;
+ resultType = refExpr->getType();
+
+ // Otherwise, try to evaluate as an l-value.
+ } else if (CEK != CEK_AsValueOnly &&
+ refExpr->EvaluateAsLValue(result, getContext())) {
+ resultIsReference = true;
+ resultType = value->getType();
+
+ // Failure.
+ } else {
+ return ConstantEmission();
+ }
+
+ // In any case, if the initializer has side-effects, abandon ship.
+ if (result.HasSideEffects)
+ return ConstantEmission();
+
+ // Emit as a constant.
+ llvm::Constant *C = CGM.EmitConstantValue(result.Val, resultType, this);
+
+ // Make sure we emit a debug reference to the global variable.
+ // This should probably fire even for
+ if (isa<VarDecl>(value)) {
+ if (!getContext().DeclMustBeEmitted(cast<VarDecl>(value)))
+ EmitDeclRefExprDbgValue(refExpr, C);
+ } else {
+ assert(isa<EnumConstantDecl>(value));
+ EmitDeclRefExprDbgValue(refExpr, C);
+ }
+
+ // If we emitted a reference constant, we need to dereference that.
+ if (resultIsReference)
+ return ConstantEmission::forReference(C);
+
+ return ConstantEmission::forValue(C);
+}
+
llvm::Value *CodeGenFunction::EmitLoadOfScalar(LValue lvalue) {
return EmitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(),
lvalue.getAlignment().getQuantity(),
@@ -1220,7 +1329,7 @@
static void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E,
LValue &LV,
bool IsMemberAccess=false) {
- if (Ctx.getLangOptions().getGC() == LangOptions::NonGC)
+ if (Ctx.getLangOpts().getGC() == LangOptions::NonGC)
return;
if (isa<ObjCIvarRefExpr>(E)) {
@@ -1383,27 +1492,34 @@
}
if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
-
// Check if this is a global variable.
if (VD->hasExternalStorage() || VD->isFileVarDecl())
return EmitGlobalVarDeclLValue(*this, E, VD);
+ bool isBlockVariable = VD->hasAttr<BlocksAttr>();
+
bool NonGCable = VD->hasLocalStorage() &&
!VD->getType()->isReferenceType() &&
- !VD->hasAttr<BlocksAttr>();
+ !isBlockVariable;
llvm::Value *V = LocalDeclMap[VD];
if (!V && VD->isStaticLocal())
V = CGM.getStaticLocalDeclAddress(VD);
// Use special handling for lambdas.
- if (!V)
+ if (!V) {
if (FieldDecl *FD = LambdaCaptureFields.lookup(VD))
return EmitLValueForField(CXXABIThisValue, FD, 0);
+ assert(isa<BlockDecl>(CurCodeDecl) && E->refersToEnclosingLocal());
+ CharUnits alignment = getContext().getDeclAlign(VD);
+ return MakeAddrLValue(GetAddrOfBlockDecl(VD, isBlockVariable),
+ E->getType(), alignment);
+ }
+
assert(V && "DeclRefExpr not entered in LocalDeclMap?");
- if (VD->hasAttr<BlocksAttr>())
+ if (isBlockVariable)
V = BuildBlockByrefAddress(V, VD);
LValue LV;
@@ -1430,11 +1546,6 @@
llvm_unreachable("Unhandled DeclRefExpr");
}
-LValue CodeGenFunction::EmitBlockDeclRefLValue(const BlockDeclRefExpr *E) {
- CharUnits Alignment = getContext().getDeclAlign(E->getDecl());
- return MakeAddrLValue(GetAddrOfBlockDecl(E), E->getType(), Alignment);
-}
-
LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
// __extension__ doesn't affect lvalue-ness.
if (E->getOpcode() == UO_Extension)
@@ -1454,8 +1565,8 @@
// of a pointer to object; as in void foo (__weak id *param); *param = 0;
// But, we continue to generate __strong write barrier on indirect write
// into a pointer to object.
- if (getContext().getLangOptions().ObjC1 &&
- getContext().getLangOptions().getGC() != LangOptions::NonGC &&
+ if (getContext().getLangOpts().ObjC1 &&
+ getContext().getLangOpts().getGC() != LangOptions::NonGC &&
LV.isObjCWeak())
LV.setNonGC(!E->isOBJCGCCandidate(getContext()));
return LV;
@@ -1655,7 +1766,7 @@
// GEP indexes are signed, and scaling an index isn't permitted to
// signed-overflow, so we use the same semantics for our explicit
// multiply. We suppress this if overflow is not undefined behavior.
- if (getLangOptions().isSignedOverflowDefined()) {
+ if (getLangOpts().isSignedOverflowDefined()) {
Idx = Builder.CreateMul(Idx, numElements);
Address = Builder.CreateGEP(Address, Idx, "arrayidx");
} else {
@@ -1690,14 +1801,14 @@
// Propagate the alignment from the array itself to the result.
ArrayAlignment = ArrayLV.getAlignment();
- if (getContext().getLangOptions().isSignedOverflowDefined())
+ if (getContext().getLangOpts().isSignedOverflowDefined())
Address = Builder.CreateGEP(ArrayPtr, Args, "arrayidx");
else
Address = Builder.CreateInBoundsGEP(ArrayPtr, Args, "arrayidx");
} else {
// The base must be a pointer, which is not an aggregate. Emit it.
llvm::Value *Base = EmitScalarExpr(E->getBase());
- if (getContext().getLangOptions().isSignedOverflowDefined())
+ if (getContext().getLangOpts().isSignedOverflowDefined())
Address = Builder.CreateGEP(Base, Idx, "arrayidx");
else
Address = Builder.CreateInBoundsGEP(Base, Idx, "arrayidx");
@@ -1720,8 +1831,8 @@
LV.getQuals().setAddressSpace(E->getBase()->getType().getAddressSpace());
- if (getContext().getLangOptions().ObjC1 &&
- getContext().getLangOptions().getGC() != LangOptions::NonGC) {
+ if (getContext().getLangOpts().ObjC1 &&
+ getContext().getLangOpts().getGC() != LangOptions::NonGC) {
LV.setNonGC(!E->isOBJCGCCandidate(getContext()));
setObjCGCLValueClass(getContext(), E, LV);
}
@@ -2229,7 +2340,7 @@
if (const CXXPseudoDestructorExpr *PseudoDtor
= dyn_cast<CXXPseudoDestructorExpr>(E->getCallee()->IgnoreParens())) {
QualType DestroyedType = PseudoDtor->getDestroyedType();
- if (getContext().getLangOptions().ObjCAutoRefCount &&
+ if (getContext().getLangOpts().ObjCAutoRefCount &&
DestroyedType->isObjCLifetimeType() &&
(DestroyedType.getObjCLifetime() == Qualifiers::OCL_Strong ||
DestroyedType.getObjCLifetime() == Qualifiers::OCL_Weak)) {
Modified: cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp Mon Mar 19 14:02:20 2012
@@ -85,7 +85,7 @@
QualType elementType, InitListExpr *E);
AggValueSlot::NeedsGCBarriers_t needsGC(QualType T) {
- if (CGF.getLangOptions().getGC() && TypeRequiresGCollection(T))
+ if (CGF.getLangOpts().getGC() && TypeRequiresGCollection(T))
return AggValueSlot::NeedsGCBarriers;
return AggValueSlot::DoesNotNeedGCBarriers;
}
@@ -109,7 +109,24 @@
}
// l-values.
- void VisitDeclRefExpr(DeclRefExpr *DRE) { EmitAggLoadOfLValue(DRE); }
+ void VisitDeclRefExpr(DeclRefExpr *E) {
+ // For aggregates, we should always be able to emit the variable
+ // as an l-value unless it's a reference. This is due to the fact
+ // that we can't actually ever see a normal l2r conversion on an
+ // aggregate in C++, and in C there's no language standard
+ // actively preventing us from listing variables in the captures
+ // list of a block.
+ if (E->getDecl()->getType()->isReferenceType()) {
+ if (CodeGenFunction::ConstantEmission result
+ = CGF.tryEmitAsConstant(E)) {
+ EmitFinalDestCopy(E, result.getReferenceLValue(CGF, E));
+ return;
+ }
+ }
+
+ EmitAggLoadOfLValue(E);
+ }
+
void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); }
void VisitUnaryDeref(UnaryOperator *E) { EmitAggLoadOfLValue(E); }
void VisitStringLiteral(StringLiteral *E) { EmitAggLoadOfLValue(E); }
@@ -117,9 +134,6 @@
void VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
EmitAggLoadOfLValue(E);
}
- void VisitBlockDeclRefExpr(const BlockDeclRefExpr *E) {
- EmitAggLoadOfLValue(E);
- }
void VisitPredefinedExpr(const PredefinedExpr *E) {
EmitAggLoadOfLValue(E);
}
@@ -240,7 +254,7 @@
// volatile.
if (Dest.isIgnored()) {
if (!Src.isVolatileQualified() ||
- CGF.CGM.getLangOptions().CPlusPlus ||
+ CGF.CGM.getLangOpts().CPlusPlus ||
(IgnoreResult && Ignore))
return;
@@ -1109,7 +1123,7 @@
if (Slot.isZeroed() || Slot.isVolatile() || Slot.getAddr() == 0) return;
// C++ objects with a user-declared constructor don't need zero'ing.
- if (CGF.getContext().getLangOptions().CPlusPlus)
+ if (CGF.getContext().getLangOpts().CPlusPlus)
if (const RecordType *RT = CGF.getContext()
.getBaseElementType(E->getType())->getAs<RecordType>()) {
const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
@@ -1181,7 +1195,7 @@
bool isVolatile, unsigned Alignment) {
assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex");
- if (getContext().getLangOptions().CPlusPlus) {
+ if (getContext().getLangOpts().CPlusPlus) {
if (const RecordType *RT = Ty->getAs<RecordType>()) {
CXXRecordDecl *Record = cast<CXXRecordDecl>(RT->getDecl());
assert((Record->hasTrivialCopyConstructor() ||
@@ -1240,7 +1254,7 @@
SrcPtr = Builder.CreateBitCast(SrcPtr, SBP);
// Don't do any of the memmove_collectable tests if GC isn't set.
- if (CGM.getLangOptions().getGC() == LangOptions::NonGC) {
+ if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
// fall through
} else if (const RecordType *RecordTy = Ty->getAs<RecordType>()) {
RecordDecl *Record = RecordTy->getDecl();
Modified: cfe/branches/tooling/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExprCXX.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExprCXX.cpp Mon Mar 19 14:02:20 2012
@@ -113,7 +113,7 @@
// When building with -fapple-kext, all calls must go through the vtable since
// the kernel linker can do runtime patching of vtables.
- if (Context.getLangOptions().AppleKext)
+ if (Context.getLangOpts().AppleKext)
return false;
// If the most derived class is marked final, we know that no subclass can
@@ -256,7 +256,7 @@
if (UseVirtualCall) {
Callee = BuildVirtualCall(Dtor, Dtor_Complete, This, Ty);
} else {
- if (getContext().getLangOptions().AppleKext &&
+ if (getContext().getLangOpts().AppleKext &&
MD->isVirtual() &&
ME->hasQualifier())
Callee = BuildAppleKextVirtualCall(MD, ME->getQualifier(), Ty);
@@ -269,7 +269,7 @@
} else if (UseVirtualCall) {
Callee = BuildVirtualCall(MD, This, Ty);
} else {
- if (getContext().getLangOptions().AppleKext &&
+ if (getContext().getLangOpts().AppleKext &&
MD->isVirtual() &&
ME->hasQualifier())
Callee = BuildAppleKextVirtualCall(MD, ME->getQualifier(), Ty);
@@ -427,7 +427,7 @@
// Elide the constructor if we're constructing from a temporary.
// The temporary check is required because Sema sets this on NRVO
// returns.
- if (getContext().getLangOptions().ElideConstructors && E->isElidable()) {
+ if (getContext().getLangOpts().ElideConstructors && E->isElidable()) {
assert(getContext().hasSameUnqualifiedType(E->getType(),
E->getArg(0)->getType()));
if (E->getArg(0)->isTemporaryObject(getContext(), CD->getParent())) {
@@ -1381,7 +1381,7 @@
if (Dtor)
CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete,
/*ForVirtualBase=*/false, Ptr);
- else if (CGF.getLangOptions().ObjCAutoRefCount &&
+ else if (CGF.getLangOpts().ObjCAutoRefCount &&
ElementType->isObjCLifetimeType()) {
switch (ElementType.getObjCLifetime()) {
case Qualifiers::OCL_None:
Modified: cfe/branches/tooling/lib/CodeGen/CGExprComplex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExprComplex.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExprComplex.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExprComplex.cpp Mon Mar 19 14:02:20 2012
@@ -111,8 +111,17 @@
}
// l-values.
- ComplexPairTy VisitDeclRefExpr(const Expr *E) { return EmitLoadOfLValue(E); }
- ComplexPairTy VisitBlockDeclRefExpr(const Expr *E) { return EmitLoadOfLValue(E); }
+ ComplexPairTy VisitDeclRefExpr(DeclRefExpr *E) {
+ if (CodeGenFunction::ConstantEmission result = CGF.tryEmitAsConstant(E)) {
+ if (result.isReference())
+ return EmitLoadOfLValue(result.getReferenceLValue(CGF, E));
+
+ llvm::ConstantStruct *pair =
+ cast<llvm::ConstantStruct>(result.getValue());
+ return ComplexPairTy(pair->getOperand(0), pair->getOperand(1));
+ }
+ return EmitLoadOfLValue(E);
+ }
ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
return EmitLoadOfLValue(E);
}
@@ -631,7 +640,7 @@
LValue LV = EmitCompoundAssignLValue(E, Func, Val);
// The result of an assignment in C is the assigned r-value.
- if (!CGF.getContext().getLangOptions().CPlusPlus)
+ if (!CGF.getContext().getLangOpts().CPlusPlus)
return Val;
// If the lvalue is non-volatile, return the computed value of the assignment.
@@ -666,7 +675,7 @@
LValue LV = EmitBinAssignLValue(E, Val);
// The result of an assignment in C is the assigned r-value.
- if (!CGF.getContext().getLangOptions().CPlusPlus)
+ if (!CGF.getContext().getLangOpts().CPlusPlus)
return Val;
// If the lvalue is non-volatile, return the computed value of the assignment.
Modified: cfe/branches/tooling/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExprConstant.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExprConstant.cpp Mon Mar 19 14:02:20 2012
@@ -763,7 +763,9 @@
llvm::Constant *EmitArrayInitialization(InitListExpr *ILE) {
unsigned NumInitElements = ILE->getNumInits();
- if (NumInitElements == 1 && ILE->getType() == ILE->getInit(0)->getType() &&
+ if (NumInitElements == 1 &&
+ CGM.getContext().hasSameUnqualifiedType(ILE->getType(),
+ ILE->getInit(0)->getType()) &&
(isa<StringLiteral>(ILE->getInit(0)) ||
isa<ObjCEncodeExpr>(ILE->getInit(0))))
return Visit(ILE->getInit(0));
Modified: cfe/branches/tooling/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExprScalar.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExprScalar.cpp Mon Mar 19 14:02:20 2012
@@ -211,48 +211,17 @@
// Otherwise, assume the mapping is the scalar directly.
return CGF.getOpaqueRValueMapping(E).getScalarVal();
}
-
+
// l-values.
Value *VisitDeclRefExpr(DeclRefExpr *E) {
- VarDecl *VD = dyn_cast<VarDecl>(E->getDecl());
- if (!VD && !isa<EnumConstantDecl>(E->getDecl()))
- return EmitLoadOfLValue(E);
- if (VD && !VD->isUsableInConstantExpressions())
- return EmitLoadOfLValue(E);
-
- // This is an enumerator or a variable which is usable in constant
- // expressions. Try to emit its value instead.
- Expr::EvalResult Result;
- bool IsReferenceConstant = false;
- QualType EvalTy = E->getType();
- if (!E->EvaluateAsRValue(Result, CGF.getContext())) {
- // If this is a reference, try to determine what it is bound to.
- if (!E->getDecl()->getType()->isReferenceType() ||
- !E->EvaluateAsLValue(Result, CGF.getContext()))
- return EmitLoadOfLValue(E);
-
- IsReferenceConstant = true;
- EvalTy = E->getDecl()->getType();
- }
-
- assert(!Result.HasSideEffects && "Constant declref with side-effect?!");
-
- llvm::Constant *C = CGF.CGM.EmitConstantValue(Result.Val, EvalTy, &CGF);
-
- // Make sure we emit a debug reference to the global variable.
- if (VD) {
- if (!CGF.getContext().DeclMustBeEmitted(VD))
- CGF.EmitDeclRefExprDbgValue(E, C);
- } else {
- assert(isa<EnumConstantDecl>(E->getDecl()));
- CGF.EmitDeclRefExprDbgValue(E, C);
+ if (CodeGenFunction::ConstantEmission result = CGF.tryEmitAsConstant(E)) {
+ if (result.isReference())
+ return EmitLoadOfLValue(result.getReferenceLValue(CGF, E));
+ return result.getValue();
}
-
- if (IsReferenceConstant)
- return EmitLoadOfLValue(CGF.MakeNaturalAlignAddrLValue(C, E->getType()));
-
- return C;
+ return EmitLoadOfLValue(E);
}
+
Value *VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
return CGF.EmitObjCSelectorExpr(E);
}
@@ -304,8 +273,6 @@
Value *VisitStmtExpr(const StmtExpr *E);
- Value *VisitBlockDeclRefExpr(const BlockDeclRefExpr *E);
-
// Unary Operators.
Value *VisitUnaryPostDec(const UnaryOperator *E) {
LValue LV = EmitLValue(E->getSubExpr());
@@ -424,7 +391,7 @@
// Binary Operators.
Value *EmitMul(const BinOpInfo &Ops) {
if (Ops.Ty->isSignedIntegerOrEnumerationType()) {
- switch (CGF.getContext().getLangOptions().getSignedOverflowBehavior()) {
+ switch (CGF.getContext().getLangOpts().getSignedOverflowBehavior()) {
case LangOptions::SOB_Undefined:
return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
case LangOptions::SOB_Defined:
@@ -439,7 +406,7 @@
return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
}
bool isTrapvOverflowBehavior() {
- return CGF.getContext().getLangOptions().getSignedOverflowBehavior()
+ return CGF.getContext().getLangOpts().getSignedOverflowBehavior()
== LangOptions::SOB_Trapping;
}
/// Create a binary op that checks for overflow.
@@ -1272,11 +1239,6 @@
.getScalarVal();
}
-Value *ScalarExprEmitter::VisitBlockDeclRefExpr(const BlockDeclRefExpr *E) {
- LValue LV = CGF.EmitBlockDeclRefLValue(E);
- return CGF.EmitLoadOfLValue(LV).getScalarVal();
-}
-
//===----------------------------------------------------------------------===//
// Unary Operators
//===----------------------------------------------------------------------===//
@@ -1285,7 +1247,7 @@
EmitAddConsiderOverflowBehavior(const UnaryOperator *E,
llvm::Value *InVal,
llvm::Value *NextVal, bool IsInc) {
- switch (CGF.getContext().getLangOptions().getSignedOverflowBehavior()) {
+ switch (CGF.getContext().getLangOpts().getSignedOverflowBehavior()) {
case LangOptions::SOB_Undefined:
return Builder.CreateNSWAdd(InVal, NextVal, IsInc ? "inc" : "dec");
case LangOptions::SOB_Defined:
@@ -1357,7 +1319,7 @@
= CGF.getContext().getAsVariableArrayType(type)) {
llvm::Value *numElts = CGF.getVLASize(vla).first;
if (!isInc) numElts = Builder.CreateNSWNeg(numElts, "vla.negsize");
- if (CGF.getContext().getLangOptions().isSignedOverflowDefined())
+ if (CGF.getContext().getLangOpts().isSignedOverflowDefined())
value = Builder.CreateGEP(value, numElts, "vla.inc");
else
value = Builder.CreateInBoundsGEP(value, numElts, "vla.inc");
@@ -1367,7 +1329,7 @@
llvm::Value *amt = Builder.getInt32(amount);
value = CGF.EmitCastToVoidPtr(value);
- if (CGF.getContext().getLangOptions().isSignedOverflowDefined())
+ if (CGF.getContext().getLangOpts().isSignedOverflowDefined())
value = Builder.CreateGEP(value, amt, "incdec.funcptr");
else
value = Builder.CreateInBoundsGEP(value, amt, "incdec.funcptr");
@@ -1376,7 +1338,7 @@
// For everything else, we can just do a simple increment.
} else {
llvm::Value *amt = Builder.getInt32(amount);
- if (CGF.getContext().getLangOptions().isSignedOverflowDefined())
+ if (CGF.getContext().getLangOpts().isSignedOverflowDefined())
value = Builder.CreateGEP(value, amt, "incdec.ptr");
else
value = Builder.CreateInBoundsGEP(value, amt, "incdec.ptr");
@@ -1437,7 +1399,7 @@
llvm::Value *sizeValue =
llvm::ConstantInt::get(CGF.SizeTy, size.getQuantity());
- if (CGF.getContext().getLangOptions().isSignedOverflowDefined())
+ if (CGF.getContext().getLangOpts().isSignedOverflowDefined())
value = Builder.CreateGEP(value, sizeValue, "incdec.objptr");
else
value = Builder.CreateInBoundsGEP(value, sizeValue, "incdec.objptr");
@@ -1778,7 +1740,7 @@
return 0;
// The result of an assignment in C is the assigned r-value.
- if (!CGF.getContext().getLangOptions().CPlusPlus)
+ if (!CGF.getContext().getLangOpts().CPlusPlus)
return RHS;
// If the lvalue is non-volatile, return the computed value of the assignment.
@@ -1839,7 +1801,7 @@
}
if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
llvm::Value *Val = Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div");
- if (CGF.getContext().getLangOptions().OpenCL) {
+ if (CGF.getContext().getLangOpts().OpenCL) {
// OpenCL 1.1 7.4: minimum accuracy of single precision / is 2.5ulp
llvm::Type *ValTy = Val->getType();
if (ValTy->isFloatTy() ||
@@ -1915,7 +1877,7 @@
// Handle overflow with llvm.trap.
const std::string *handlerName =
- &CGF.getContext().getLangOptions().OverflowHandler;
+ &CGF.getContext().getLangOpts().OverflowHandler;
if (handlerName->empty()) {
EmitOverflowBB(overflowBB);
Builder.SetInsertPoint(continueBB);
@@ -2014,7 +1976,7 @@
// GEP indexes are signed, and scaling an index isn't permitted to
// signed-overflow, so we use the same semantics for our explicit
// multiply. We suppress this if overflow is not undefined behavior.
- if (CGF.getLangOptions().isSignedOverflowDefined()) {
+ if (CGF.getLangOpts().isSignedOverflowDefined()) {
index = CGF.Builder.CreateMul(index, numElements, "vla.index");
pointer = CGF.Builder.CreateGEP(pointer, index, "add.ptr");
} else {
@@ -2033,7 +1995,7 @@
return CGF.Builder.CreateBitCast(result, pointer->getType());
}
- if (CGF.getLangOptions().isSignedOverflowDefined())
+ if (CGF.getLangOpts().isSignedOverflowDefined())
return CGF.Builder.CreateGEP(pointer, index, "add.ptr");
return CGF.Builder.CreateInBoundsGEP(pointer, index, "add.ptr");
@@ -2045,7 +2007,7 @@
return emitPointerArithmetic(CGF, op, /*subtraction*/ false);
if (op.Ty->isSignedIntegerOrEnumerationType()) {
- switch (CGF.getContext().getLangOptions().getSignedOverflowBehavior()) {
+ switch (CGF.getContext().getLangOpts().getSignedOverflowBehavior()) {
case LangOptions::SOB_Undefined:
return Builder.CreateNSWAdd(op.LHS, op.RHS, "add");
case LangOptions::SOB_Defined:
@@ -2065,7 +2027,7 @@
// The LHS is always a pointer if either side is.
if (!op.LHS->getType()->isPointerTy()) {
if (op.Ty->isSignedIntegerOrEnumerationType()) {
- switch (CGF.getContext().getLangOptions().getSignedOverflowBehavior()) {
+ switch (CGF.getContext().getLangOpts().getSignedOverflowBehavior()) {
case LangOptions::SOB_Undefined:
return Builder.CreateNSWSub(op.LHS, op.RHS, "sub");
case LangOptions::SOB_Defined:
@@ -2391,7 +2353,7 @@
return 0;
// The result of an assignment in C is the assigned r-value.
- if (!CGF.getContext().getLangOptions().CPlusPlus)
+ if (!CGF.getContext().getLangOpts().CPlusPlus)
return RHS;
// If the lvalue is non-volatile, return the computed value of the assignment.
@@ -2605,7 +2567,7 @@
// OpenCL: If the condition is a vector, we can treat this condition like
// the select function.
- if (CGF.getContext().getLangOptions().OpenCL
+ if (CGF.getContext().getLangOpts().OpenCL
&& condExpr->getType()->isVectorType()) {
llvm::Value *CondV = CGF.EmitScalarExpr(condExpr);
llvm::Value *LHS = Visit(lhsExpr);
Modified: cfe/branches/tooling/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGObjC.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGObjC.cpp Mon Mar 19 14:02:20 2012
@@ -279,7 +279,7 @@
// though.
bool retainSelf =
(!isDelegateInit &&
- CGM.getLangOptions().ObjCAutoRefCount &&
+ CGM.getLangOpts().ObjCAutoRefCount &&
method &&
method->hasAttr<NSConsumesSelfAttr>());
@@ -333,7 +333,7 @@
// In ARC, we sometimes want to "extend the lifetime"
// (i.e. retain+autorelease) of receivers of returns-inner-pointer
// messages.
- if (getLangOptions().ObjCAutoRefCount && method &&
+ if (getLangOpts().ObjCAutoRefCount && method &&
method->hasAttr<ObjCReturnsInnerPointerAttr>() &&
shouldExtendReceiverForInnerPointerMessage(E))
Receiver = EmitARCRetainAutorelease(ReceiverType, Receiver);
@@ -352,7 +352,7 @@
// be an undefined read and write of an object in unordered
// expressions.
if (isDelegateInit) {
- assert(getLangOptions().ObjCAutoRefCount &&
+ assert(getLangOpts().ObjCAutoRefCount &&
"delegate init calls should only be marked in ARC");
// Do an unsafe store of null into self.
@@ -458,7 +458,7 @@
StartFunction(OMD, OMD->getResultType(), Fn, FI, args, StartLoc);
// In ARC, certain methods get an extra cleanup.
- if (CGM.getLangOptions().ObjCAutoRefCount &&
+ if (CGM.getLangOpts().ObjCAutoRefCount &&
OMD->isInstanceMethod() &&
OMD->getSelector().isUnarySelector()) {
const IdentifierInfo *ident =
@@ -604,13 +604,13 @@
// Handle retain.
if (setterKind == ObjCPropertyDecl::Retain) {
// In GC-only, there's nothing special that needs to be done.
- if (CGM.getLangOptions().getGC() == LangOptions::GCOnly) {
+ if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
// fallthrough
// In ARC, if the property is non-atomic, use expression emission,
// which translates to objc_storeStrong. This isn't required, but
// it's slightly nicer.
- } else if (CGM.getLangOptions().ObjCAutoRefCount && !IsAtomic) {
+ } else if (CGM.getLangOpts().ObjCAutoRefCount && !IsAtomic) {
Kind = Expression;
return;
@@ -645,14 +645,14 @@
// expressions. This actually works out to being atomic anyway,
// except for ARC __strong, but that should trigger the above code.
if (ivarType.hasNonTrivialObjCLifetime() ||
- (CGM.getLangOptions().getGC() &&
+ (CGM.getLangOpts().getGC() &&
CGM.getContext().getObjCGCAttrKind(ivarType))) {
Kind = Expression;
return;
}
// Compute whether the ivar has strong members.
- if (CGM.getLangOptions().getGC())
+ if (CGM.getLangOpts().getGC())
if (const RecordType *recordType = ivarType->getAs<RecordType>())
HasStrong = recordType->getDecl()->hasObjectMember();
@@ -931,7 +931,7 @@
// The second argument is the address of the parameter variable.
ParmVarDecl *argVar = *OMD->param_begin();
- DeclRefExpr argRef(argVar, argVar->getType().getNonReferenceType(),
+ DeclRefExpr argRef(argVar, false, argVar->getType().getNonReferenceType(),
VK_LValue, SourceLocation());
llvm::Value *argAddr = CGF.EmitLValue(&argRef).getAddress();
argAddr = CGF.Builder.CreateBitCast(argAddr, CGF.Int8PtrTy);
@@ -976,7 +976,7 @@
// The second argument is the address of the parameter variable.
ParmVarDecl *argVar = *OMD->param_begin();
- DeclRefExpr argRef(argVar, argVar->getType().getNonReferenceType(),
+ DeclRefExpr argRef(argVar, false, argVar->getType().getNonReferenceType(),
VK_LValue, SourceLocation());
llvm::Value *argAddr = CGF.EmitLValue(&argRef).getAddress();
argAddr = CGF.Builder.CreateBitCast(argAddr, CGF.Int8PtrTy);
@@ -1020,24 +1020,15 @@
return false;
}
-bool UseOptimizedSetter(CodeGenModule &CGM) {
- if (CGM.getLangOptions().getGC() != LangOptions::NonGC)
+static bool UseOptimizedSetter(CodeGenModule &CGM) {
+ if (CGM.getLangOpts().getGC() != LangOptions::NonGC)
return false;
const TargetInfo &Target = CGM.getContext().getTargetInfo();
- StringRef TargetPlatform = Target.getPlatformName();
- if (TargetPlatform.empty())
- return false;
- VersionTuple TargetMinVersion = Target.getPlatformMinVersion();
-
- if (TargetPlatform.compare("macosx") ||
- TargetMinVersion.getMajor() <= 9)
+
+ if (Target.getPlatformName() != "macosx")
return false;
-
- unsigned minor = 0;
- if (llvm::Optional<unsigned> Minor = TargetMinVersion.getMinor())
- minor = *Minor;
-
- return (minor >= 8);
+
+ return Target.getPlatformMinVersion() >= VersionTuple(10, 8);
}
void
@@ -1163,7 +1154,8 @@
// Otherwise, fake up some ASTs and emit a normal assignment.
ValueDecl *selfDecl = setterMethod->getSelfDecl();
- DeclRefExpr self(selfDecl, selfDecl->getType(), VK_LValue, SourceLocation());
+ DeclRefExpr self(selfDecl, false, selfDecl->getType(),
+ VK_LValue, SourceLocation());
ImplicitCastExpr selfLoad(ImplicitCastExpr::OnStack,
selfDecl->getType(), CK_LValueToRValue, &self,
VK_RValue);
@@ -1172,7 +1164,7 @@
ParmVarDecl *argDecl = *setterMethod->param_begin();
QualType argType = argDecl->getType().getNonReferenceType();
- DeclRefExpr arg(argDecl, argType, VK_LValue, SourceLocation());
+ DeclRefExpr arg(argDecl, false, argType, VK_LValue, SourceLocation());
ImplicitCastExpr argLoad(ImplicitCastExpr::OnStack,
argType.getUnqualifiedType(), CK_LValueToRValue,
&arg, VK_RValue);
@@ -1342,7 +1334,7 @@
}
bool CodeGenFunction::IvarTypeWithAggrGCObjects(QualType Ty) {
- if (CGM.getLangOptions().getGC() == LangOptions::NonGC)
+ if (CGM.getLangOpts().getGC() == LangOptions::NonGC)
return false;
if (const RecordType *FDTTy = Ty.getTypePtr()->getAs<RecordType>())
return FDTTy->getDecl()->hasObjectMember();
@@ -1407,7 +1399,7 @@
// Emit the collection pointer. In ARC, we do a retain.
llvm::Value *Collection;
- if (getLangOptions().ObjCAutoRefCount) {
+ if (getLangOpts().ObjCAutoRefCount) {
Collection = EmitARCRetainScalarExpr(S.getCollection());
// Enter a cleanup to do the release.
@@ -1525,7 +1517,7 @@
EmitAutoVarInit(variable);
const VarDecl* D = cast<VarDecl>(SD->getSingleDecl());
- DeclRefExpr tempDRE(const_cast<VarDecl*>(D), D->getType(),
+ DeclRefExpr tempDRE(const_cast<VarDecl*>(D), false, D->getType(),
VK_LValue, SourceLocation());
elementLValue = EmitLValue(&tempDRE);
elementType = D->getType();
@@ -1632,7 +1624,7 @@
DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd());
// Leave the cleanup we entered in ARC.
- if (getLangOptions().ObjCAutoRefCount)
+ if (getLangOpts().ObjCAutoRefCount)
PopCleanupBlock();
EmitBlock(LoopEnd.getBlock());
@@ -2249,7 +2241,7 @@
}
void CodeGenFunction::EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr) {
- if (CGM.getLangOptions().ObjCAutoRefCount)
+ if (CGM.getLangOpts().ObjCAutoRefCount)
EHStack.pushCleanup<CallObjCAutoreleasePoolObject>(NormalCleanup, Ptr);
else
EHStack.pushCleanup<CallObjCMRRAutoreleasePoolObject>(NormalCleanup, Ptr);
@@ -2300,7 +2292,7 @@
// As a very special optimization, in ARC++, if the l-value is the
// result of a non-volatile assignment, do a simple retain of the
// result of the call to objc_storeWeak instead of reloading.
- if (CGF.getLangOptions().CPlusPlus &&
+ if (CGF.getLangOpts().CPlusPlus &&
!type.isVolatileQualified() &&
type.getObjCLifetime() == Qualifiers::OCL_Weak &&
isa<BinaryOperator>(e) &&
@@ -2645,7 +2637,7 @@
llvm::Value *CodeGenFunction::EmitObjCThrowOperand(const Expr *expr) {
// In ARC, retain and autorelease the expression.
- if (getLangOptions().ObjCAutoRefCount) {
+ if (getLangOpts().ObjCAutoRefCount) {
// Do so before running any cleanups for the full-expression.
// tryEmitARCRetainScalarExpr does make an effort to do things
// inside cleanups, but there are crazy cases like
@@ -2762,7 +2754,7 @@
CodeGenFunction::GenerateObjCAtomicSetterCopyHelperFunction(
const ObjCPropertyImplDecl *PID) {
// FIXME. This api is for NeXt runtime only for now.
- if (!getLangOptions().CPlusPlus || !getLangOptions().NeXTRuntime)
+ if (!getLangOpts().CPlusPlus || !getLangOpts().NeXTRuntime)
return 0;
QualType Ty = PID->getPropertyIvarDecl()->getType();
if (!Ty->isRecordType())
@@ -2817,28 +2809,23 @@
StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation());
- DeclRefExpr *DstExpr =
- new (C) DeclRefExpr(&dstDecl, DestTy,
- VK_RValue, SourceLocation());
-
- Expr* DST = new (C) UnaryOperator(DstExpr, UO_Deref, DestTy->getPointeeType(),
- VK_LValue, OK_Ordinary, SourceLocation());
-
- DeclRefExpr *SrcExpr =
- new (C) DeclRefExpr(&srcDecl, SrcTy,
- VK_RValue, SourceLocation());
+ DeclRefExpr DstExpr(&dstDecl, false, DestTy,
+ VK_RValue, SourceLocation());
+ UnaryOperator DST(&DstExpr, UO_Deref, DestTy->getPointeeType(),
+ VK_LValue, OK_Ordinary, SourceLocation());
- Expr* SRC = new (C) UnaryOperator(SrcExpr, UO_Deref, SrcTy->getPointeeType(),
- VK_LValue, OK_Ordinary, SourceLocation());
+ DeclRefExpr SrcExpr(&srcDecl, false, SrcTy,
+ VK_RValue, SourceLocation());
+ UnaryOperator SRC(&SrcExpr, UO_Deref, SrcTy->getPointeeType(),
+ VK_LValue, OK_Ordinary, SourceLocation());
- Expr *Args[2] = { DST, SRC };
+ Expr *Args[2] = { &DST, &SRC };
CallExpr *CalleeExp = cast<CallExpr>(PID->getSetterCXXAssignment());
- CXXOperatorCallExpr *TheCall =
- new (C) CXXOperatorCallExpr(C, OO_Equal, CalleeExp->getCallee(),
- Args, 2, DestTy->getPointeeType(),
- VK_LValue, SourceLocation());
-
- EmitStmt(TheCall);
+ CXXOperatorCallExpr TheCall(C, OO_Equal, CalleeExp->getCallee(),
+ Args, 2, DestTy->getPointeeType(),
+ VK_LValue, SourceLocation());
+
+ EmitStmt(&TheCall);
FinishFunction();
HelperFn = llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);
@@ -2850,7 +2837,7 @@
CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction(
const ObjCPropertyImplDecl *PID) {
// FIXME. This api is for NeXt runtime only for now.
- if (!getLangOptions().CPlusPlus || !getLangOptions().NeXTRuntime)
+ if (!getLangOpts().CPlusPlus || !getLangOpts().NeXTRuntime)
return 0;
const ObjCPropertyDecl *PD = PID->getPropertyDecl();
QualType Ty = PD->getType();
@@ -2907,18 +2894,17 @@
StartFunction(FD, C.VoidTy, Fn, FI, args, SourceLocation());
- DeclRefExpr *SrcExpr =
- new (C) DeclRefExpr(&srcDecl, SrcTy,
+ DeclRefExpr SrcExpr(&srcDecl, false, SrcTy,
VK_RValue, SourceLocation());
- Expr* SRC = new (C) UnaryOperator(SrcExpr, UO_Deref, SrcTy->getPointeeType(),
- VK_LValue, OK_Ordinary, SourceLocation());
+ UnaryOperator SRC(&SrcExpr, UO_Deref, SrcTy->getPointeeType(),
+ VK_LValue, OK_Ordinary, SourceLocation());
CXXConstructExpr *CXXConstExpr =
cast<CXXConstructExpr>(PID->getGetterCXXConstructor());
SmallVector<Expr*, 4> ConstructorArgs;
- ConstructorArgs.push_back(SRC);
+ ConstructorArgs.push_back(&SRC);
CXXConstructExpr::arg_iterator A = CXXConstExpr->arg_begin();
++A;
@@ -2936,11 +2922,10 @@
CXXConstExpr->requiresZeroInitialization(),
CXXConstExpr->getConstructionKind(), SourceRange());
- DeclRefExpr *DstExpr =
- new (C) DeclRefExpr(&dstDecl, DestTy,
- VK_RValue, SourceLocation());
+ DeclRefExpr DstExpr(&dstDecl, false, DestTy,
+ VK_RValue, SourceLocation());
- RValue DV = EmitAnyExpr(DstExpr);
+ RValue DV = EmitAnyExpr(&DstExpr);
CharUnits Alignment = getContext().getTypeAlignInChars(TheCXXConstructExpr->getType());
EmitAggExpr(TheCXXConstructExpr,
AggValueSlot::forAddr(DV.getScalarVal(), Alignment, Qualifiers(),
Modified: cfe/branches/tooling/lib/CodeGen/CGObjCGNU.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGObjCGNU.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGObjCGNU.cpp Mon Mar 19 14:02:20 2012
@@ -641,7 +641,7 @@
SlotLookupSuperFn.init(&CGM, "objc_slot_lookup_super", SlotTy,
PtrToObjCSuperTy, SelectorTy, NULL);
// If we're in ObjC++ mode, then we want to make
- if (CGM.getLangOptions().CPlusPlus) {
+ if (CGM.getLangOpts().CPlusPlus) {
llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
// void *__cxa_begin_catch(void *e)
EnterCatchFn.init(&CGM, "__cxa_begin_catch", PtrTy, PtrTy, NULL);
@@ -773,7 +773,7 @@
IMPTy = llvm::PointerType::getUnqual(llvm::FunctionType::get(IdTy, IMPArgs,
true));
- const LangOptions &Opts = CGM.getLangOptions();
+ const LangOptions &Opts = CGM.getLangOpts();
if ((Opts.getGC() != LangOptions::NonGC) || Opts.ObjCAutoRefCount)
RuntimeVersion = 10;
@@ -882,14 +882,14 @@
}
llvm::Constant *CGObjCGNU::GetEHType(QualType T) {
- if (!CGM.getLangOptions().CPlusPlus) {
+ if (!CGM.getLangOpts().CPlusPlus) {
if (T->isObjCIdType()
|| T->isObjCQualifiedIdType()) {
// With the old ABI, there was only one kind of catchall, which broke
// foreign exceptions. With the new ABI, we use __objc_id_typeinfo as
// a pointer indicating object catchalls, and NULL to indicate real
// catchalls
- if (CGM.getLangOptions().ObjCNonFragileABI) {
+ if (CGM.getLangOpts().ObjCNonFragileABI) {
return MakeConstantString("@id");
} else {
return 0;
@@ -973,7 +973,7 @@
if (old != ObjCStrings.end())
return old->getValue();
- StringRef StringClass = CGM.getLangOptions().ObjCConstantStringClass;
+ StringRef StringClass = CGM.getLangOpts().ObjCConstantStringClass;
if (StringClass.empty()) StringClass = "NXConstantString";
@@ -1016,7 +1016,7 @@
const CallArgList &CallArgs,
const ObjCMethodDecl *Method) {
CGBuilderTy &Builder = CGF.Builder;
- if (CGM.getLangOptions().getGC() == LangOptions::GCOnly) {
+ if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
if (Sel == RetainSel || Sel == AutoreleaseSel) {
return RValue::get(EnforceType(Builder, Receiver,
CGM.getTypes().ConvertType(ResultType)));
@@ -1119,7 +1119,7 @@
CGBuilderTy &Builder = CGF.Builder;
// Strip out message sends to retain / release in GC mode
- if (CGM.getLangOptions().getGC() == LangOptions::GCOnly) {
+ if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
if (Sel == RetainSel || Sel == AutoreleaseSel) {
return RValue::get(EnforceType(Builder, Receiver,
CGM.getTypes().ConvertType(ResultType)));
@@ -1983,7 +1983,7 @@
Context.getASTObjCInterfaceLayout(SuperClassDecl).getSize().getQuantity();
// For non-fragile ivars, set the instance size to 0 - {the size of just this
// class}. The runtime will then set this to the correct value on load.
- if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
+ if (CGM.getContext().getLangOpts().ObjCNonFragileABI) {
instanceSize = 0 - (instanceSize - superInstanceSize);
}
@@ -1998,7 +1998,7 @@
// Get the offset
uint64_t BaseOffset = ComputeIvarBaseOffset(CGM, OID, IVD);
uint64_t Offset = BaseOffset;
- if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
+ if (CGM.getContext().getLangOpts().ObjCNonFragileABI) {
Offset = BaseOffset - superInstanceSize;
}
llvm::Constant *OffsetValue = llvm::ConstantInt::get(IntTy, Offset);
@@ -2070,9 +2070,9 @@
}
// Collect the names of referenced protocols
SmallVector<std::string, 16> Protocols;
- const ObjCList<ObjCProtocolDecl> &Protos =ClassDecl->getReferencedProtocols();
- for (ObjCList<ObjCProtocolDecl>::iterator I = Protos.begin(),
- E = Protos.end(); I != E; ++I)
+ for (ObjCInterfaceDecl::protocol_iterator
+ I = ClassDecl->protocol_begin(),
+ E = ClassDecl->protocol_end(); I != E; ++I)
Protocols.push_back((*I)->getNameAsString());
@@ -2192,7 +2192,7 @@
ConstantStrings.size() + 1);
ConstantStrings.push_back(NULLPtr);
- StringRef StringClass = CGM.getLangOptions().ObjCConstantStringClass;
+ StringRef StringClass = CGM.getLangOpts().ObjCConstantStringClass;
if (StringClass.empty()) StringClass = "NXConstantString";
@@ -2320,12 +2320,12 @@
Elements.push_back(SymTab);
if (RuntimeVersion >= 10)
- switch (CGM.getLangOptions().getGC()) {
+ switch (CGM.getLangOpts().getGC()) {
case LangOptions::GCOnly:
Elements.push_back(llvm::ConstantInt::get(IntTy, 2));
break;
case LangOptions::NonGC:
- if (CGM.getLangOptions().ObjCAutoRefCount)
+ if (CGM.getLangOpts().ObjCAutoRefCount)
Elements.push_back(llvm::ConstantInt::get(IntTy, 1));
else
Elements.push_back(llvm::ConstantInt::get(IntTy, 0));
@@ -2592,7 +2592,7 @@
// to replace it with the real version for a library. In non-PIC code you
// must compile with the fragile ABI if you want to use ivars from a
// GCC-compiled class.
- if (CGM.getLangOptions().PICLevel) {
+ if (CGM.getLangOpts().PICLevel) {
llvm::GlobalVariable *IvarOffsetGV = new llvm::GlobalVariable(TheModule,
Int32Ty, false,
llvm::GlobalValue::PrivateLinkage, OffsetGuess, Name+".guess");
@@ -2638,7 +2638,7 @@
llvm::Value *CGObjCGNU::EmitIvarOffset(CodeGenFunction &CGF,
const ObjCInterfaceDecl *Interface,
const ObjCIvarDecl *Ivar) {
- if (CGM.getLangOptions().ObjCNonFragileABI) {
+ if (CGM.getLangOpts().ObjCNonFragileABI) {
Interface = FindIvarInterface(CGM.getContext(), Interface, Ivar);
if (RuntimeVersion < 10)
return CGF.Builder.CreateZExtOrBitCast(
@@ -2660,7 +2660,7 @@
CGObjCRuntime *
clang::CodeGen::CreateGNUObjCRuntime(CodeGenModule &CGM) {
- if (CGM.getLangOptions().ObjCNonFragileABI)
+ if (CGM.getLangOpts().ObjCNonFragileABI)
return new CGObjCGNUstep(CGM);
return new CGObjCGCC(CGM);
}
Modified: cfe/branches/tooling/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGObjCMac.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGObjCMac.cpp Mon Mar 19 14:02:20 2012
@@ -1615,7 +1615,7 @@
llvm::Constant *CGObjCCommonMac::GenerateConstantString(
const StringLiteral *SL) {
- return (CGM.getLangOptions().NoConstantCFStrings == 0 ?
+ return (CGM.getLangOpts().NoConstantCFStrings == 0 ?
CGM.GetAddrOfConstantCFString(SL) :
CGM.GetAddrOfConstantString(SL));
}
@@ -1747,7 +1747,7 @@
}
bool requiresnullCheck = false;
- if (CGM.getLangOptions().ObjCAutoRefCount && Method)
+ if (CGM.getLangOpts().ObjCAutoRefCount && Method)
for (ObjCMethodDecl::param_const_iterator i = Method->param_begin(),
e = Method->param_end(); i != e; ++i) {
const ParmVarDecl *ParamDecl = (*i);
@@ -1789,8 +1789,8 @@
const CGBlockInfo &blockInfo) {
llvm::Constant *nullPtr = llvm::Constant::getNullValue(CGM.Int8PtrTy);
- if (CGM.getLangOptions().getGC() == LangOptions::NonGC &&
- !CGM.getLangOptions().ObjCAutoRefCount)
+ if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
+ !CGM.getLangOpts().ObjCAutoRefCount)
return nullPtr;
bool hasUnion = false;
@@ -1858,7 +1858,7 @@
std::string BitMap;
llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
- if (CGM.getLangOptions().ObjCGCBitmapPrint) {
+ if (CGM.getLangOpts().ObjCGCBitmapPrint) {
printf("\n block variable layout for block: ");
const unsigned char *s = (unsigned char*)BitMap.c_str();
for (unsigned i = 0, e = BitMap.size(); i < e; i++)
@@ -3630,7 +3630,7 @@
Mod.addModuleFlag(llvm::Module::Error, "Objective-C Image Info Section",
llvm::MDString::get(VMContext,Section));
- if (CGM.getLangOptions().getGC() == LangOptions::NonGC) {
+ if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
// Non-GC overrides those files which specify GC.
Mod.addModuleFlag(llvm::Module::Override,
"Objective-C Garbage Collection", (uint32_t)0);
@@ -3640,7 +3640,7 @@
"Objective-C Garbage Collection",
eImageInfo_GarbageCollected);
- if (CGM.getLangOptions().getGC() == LangOptions::GCOnly) {
+ if (CGM.getLangOpts().getGC() == LangOptions::GCOnly) {
// Add the ObjC GC Only value.
Mod.addModuleFlag(llvm::Module::Error, "Objective-C GC Only",
eImageInfo_GCOnly);
@@ -3837,7 +3837,7 @@
return;
unsigned WordSizeInBits = CGM.getContext().getTargetInfo().getPointerWidth(0);
unsigned ByteSizeInBits = CGM.getContext().getTargetInfo().getCharWidth();
- if (!RD && CGM.getLangOptions().ObjCAutoRefCount) {
+ if (!RD && CGM.getLangOpts().ObjCAutoRefCount) {
const FieldDecl *FirstField = RecFields[0];
FirstFieldDelta =
ComputeIvarBaseOffset(CGM, OI, cast<ObjCIvarDecl>(FirstField));
@@ -4131,13 +4131,13 @@
bool hasUnion = false;
llvm::Type *PtrTy = CGM.Int8PtrTy;
- if (CGM.getLangOptions().getGC() == LangOptions::NonGC &&
- !CGM.getLangOptions().ObjCAutoRefCount)
+ if (CGM.getLangOpts().getGC() == LangOptions::NonGC &&
+ !CGM.getLangOpts().ObjCAutoRefCount)
return llvm::Constant::getNullValue(PtrTy);
const ObjCInterfaceDecl *OI = OMD->getClassInterface();
SmallVector<const FieldDecl*, 32> RecFields;
- if (CGM.getLangOptions().ObjCAutoRefCount) {
+ if (CGM.getLangOpts().ObjCAutoRefCount) {
for (const ObjCIvarDecl *IVD = OI->all_declared_ivar_begin();
IVD; IVD = IVD->getNextIvar())
RecFields.push_back(cast<FieldDecl>(IVD));
@@ -4169,7 +4169,7 @@
std::string BitMap;
llvm::Constant *C = BuildIvarLayoutBitmap(BitMap);
- if (CGM.getLangOptions().ObjCGCBitmapPrint) {
+ if (CGM.getLangOpts().ObjCGCBitmapPrint) {
printf("\n%s ivar layout for class '%s': ",
ForStrongLayout ? "strong" : "weak",
OMD->getClassInterface()->getName().data());
@@ -4891,7 +4891,7 @@
// These are vtable-based if GC is disabled.
// Optimistically use vtable dispatch for hybrid compiles.
- if (CGM.getLangOptions().getGC() != LangOptions::GCOnly) {
+ if (CGM.getLangOpts().getGC() != LangOptions::GCOnly) {
VTableDispatchMethods.insert(GetNullarySelector("retain"));
VTableDispatchMethods.insert(GetNullarySelector("release"));
VTableDispatchMethods.insert(GetNullarySelector("autorelease"));
@@ -4907,7 +4907,7 @@
// These are vtable-based if GC is enabled.
// Optimistically use vtable dispatch for hybrid compiles.
- if (CGM.getLangOptions().getGC() != LangOptions::NonGC) {
+ if (CGM.getLangOpts().getGC() != LangOptions::NonGC) {
VTableDispatchMethods.insert(GetNullarySelector("hash"));
VTableDispatchMethods.insert(GetUnarySelector("addObject"));
@@ -4961,7 +4961,7 @@
std::string ClassName = ID->getNameAsString();
llvm::Constant *Values[10]; // 11 for 64bit targets!
- if (CGM.getLangOptions().ObjCAutoRefCount)
+ if (CGM.getLangOpts().ObjCAutoRefCount)
flags |= CLS_COMPILED_BY_ARC;
Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags);
@@ -5877,7 +5877,7 @@
}
bool requiresnullCheck = false;
- if (CGM.getLangOptions().ObjCAutoRefCount && method)
+ if (CGM.getLangOpts().ObjCAutoRefCount && method)
for (ObjCMethodDecl::param_const_iterator i = method->param_begin(),
e = method->param_end(); i != e; ++i) {
const ParmVarDecl *ParamDecl = (*i);
@@ -6344,7 +6344,7 @@
ID->getIdentifier()->getName()));
}
- if (CGM.getLangOptions().getVisibilityMode() == HiddenVisibility)
+ if (CGM.getLangOpts().getVisibilityMode() == HiddenVisibility)
Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
Entry->setAlignment(CGM.getTargetData().getABITypeAlignment(
ObjCTypes.EHTypeTy));
@@ -6363,7 +6363,7 @@
CodeGen::CGObjCRuntime *
CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) {
- if (CGM.getLangOptions().ObjCNonFragileABI)
+ if (CGM.getLangOpts().ObjCNonFragileABI)
return new CGObjCNonFragileABIMac(CGM);
return new CGObjCMac(CGM);
}
Modified: cfe/branches/tooling/lib/CodeGen/CGObjCRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGObjCRuntime.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGObjCRuntime.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGObjCRuntime.cpp Mon Mar 19 14:02:20 2012
@@ -310,7 +310,7 @@
// ARC release and lock-release cleanups.
const Expr *lockExpr = S.getSynchExpr();
llvm::Value *lock;
- if (CGF.getLangOptions().ObjCAutoRefCount) {
+ if (CGF.getLangOpts().ObjCAutoRefCount) {
lock = CGF.EmitARCRetainScalarExpr(lockExpr);
lock = CGF.EmitObjCConsumeObject(lockExpr->getType(), lock);
} else {
Modified: cfe/branches/tooling/lib/CodeGen/CGRTTI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGRTTI.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGRTTI.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGRTTI.cpp Mon Mar 19 14:02:20 2012
@@ -249,7 +249,7 @@
ASTContext &Context = CGM.getContext();
// If RTTI is disabled, don't consider key functions.
- if (!Context.getLangOptions().RTTI) return false;
+ if (!Context.getLangOpts().RTTI) return false;
if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
@@ -326,7 +326,7 @@
return llvm::GlobalValue::InternalLinkage;
case ExternalLinkage:
- if (!CGM.getLangOptions().RTTI) {
+ if (!CGM.getLangOpts().RTTI) {
// RTTI is not enabled, which means that this type info struct is going
// to be used for exception handling. Give it linkonce_odr linkage.
return llvm::GlobalValue::LinkOnceODRLinkage;
@@ -982,10 +982,10 @@
// Return a bogus pointer if RTTI is disabled, unless it's for EH.
// FIXME: should we even be calling this method if RTTI is disabled
// and it's not for EH?
- if (!ForEH && !getContext().getLangOptions().RTTI)
+ if (!ForEH && !getContext().getLangOpts().RTTI)
return llvm::Constant::getNullValue(Int8PtrTy);
- if (ForEH && Ty->isObjCObjectPointerType() && !Features.NeXTRuntime)
+ if (ForEH && Ty->isObjCObjectPointerType() && !LangOpts.NeXTRuntime)
return ObjCRuntime->GetEHType(Ty);
return RTTIBuilder(*this).BuildTypeInfo(Ty);
Modified: cfe/branches/tooling/lib/CodeGen/CGRecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGRecordLayoutBuilder.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGRecordLayoutBuilder.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGRecordLayoutBuilder.cpp Mon Mar 19 14:02:20 2012
@@ -972,7 +972,7 @@
return;
// Can only have member pointers if we're compiling C++.
- if (!Types.getContext().getLangOptions().CPlusPlus)
+ if (!Types.getContext().getLangOpts().CPlusPlus)
return;
const Type *elementType = T->getBaseElementTypeUnsafe();
@@ -1017,7 +1017,7 @@
RL->BitFields.swap(Builder.BitFields);
// Dump the layout, if requested.
- if (getContext().getLangOptions().DumpRecordLayouts) {
+ if (getContext().getLangOpts().DumpRecordLayouts) {
llvm::errs() << "\n*** Dumping IRgen Record Layout\n";
llvm::errs() << "Record: ";
D->dump();
Modified: cfe/branches/tooling/lib/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGStmt.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGStmt.cpp Mon Mar 19 14:02:20 2012
@@ -1295,6 +1295,8 @@
const VarDecl *Variable = dyn_cast<VarDecl>(&Value);
if (!Variable)
return Constraint;
+ if (Variable->getStorageClass() != SC_Register)
+ return Constraint;
AsmLabelAttr *Attr = Variable->getAttr<AsmLabelAttr>();
if (!Attr)
return Constraint;
@@ -1370,7 +1372,7 @@
StringRef StrVal = Str->getString();
if (!StrVal.empty()) {
const SourceManager &SM = CGF.CGM.getContext().getSourceManager();
- const LangOptions &LangOpts = CGF.CGM.getLangOptions();
+ const LangOptions &LangOpts = CGF.CGM.getLangOpts();
// Add the location of the start of each subsequent line of the asm to the
// MDNode.
Modified: cfe/branches/tooling/lib/CodeGen/CGVTables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGVTables.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGVTables.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGVTables.cpp Mon Mar 19 14:02:20 2012
@@ -52,7 +52,7 @@
// If we're building with optimization, we always emit VTables since that
// allows for virtual function calls to be devirtualized.
// (We don't want to do this in -fapple-kext mode however).
- if (CGM.getCodeGenOpts().OptimizationLevel && !CGM.getLangOptions().AppleKext)
+ if (CGM.getCodeGenOpts().OptimizationLevel && !CGM.getLangOpts().AppleKext)
return true;
return KeyFunction->hasBody();
Modified: cfe/branches/tooling/lib/CodeGen/CodeGenAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenAction.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenAction.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenAction.cpp Mon Mar 19 14:02:20 2012
@@ -23,6 +23,7 @@
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Support/IRReader.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -393,8 +394,17 @@
StringRef Msg = Err.getMessage();
if (Msg.startswith("error: "))
Msg = Msg.substr(7);
+
+ // Escape '%', which is interpreted as a format character.
+ llvm::SmallString<128> EscapedMessage;
+ for (unsigned i = 0, e = Msg.size(); i != e; ++i) {
+ if (Msg[i] == '%')
+ EscapedMessage += '%';
+ EscapedMessage += Msg[i];
+ }
+
unsigned DiagID = CI.getDiagnostics().getCustomDiagID(
- DiagnosticsEngine::Error, Msg);
+ DiagnosticsEngine::Error, EscapedMessage);
CI.getDiagnostics().Report(Loc, DiagID);
return;
Modified: cfe/branches/tooling/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenFunction.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenFunction.cpp Mon Mar 19 14:02:20 2012
@@ -40,7 +40,7 @@
CXXVTTValue(0), OutermostConditional(0), TerminateLandingPad(0),
TerminateHandler(0), TrapBB(0) {
- CatchUndefined = getContext().getLangOptions().CatchUndefined;
+ CatchUndefined = getContext().getLangOpts().CatchUndefined;
CGM.getCXXABI().getMangleContext().startNewFunction();
}
@@ -266,15 +266,16 @@
// Pass inline keyword to optimizer if it appears explicitly on any
// declaration.
- if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
- for (FunctionDecl::redecl_iterator RI = FD->redecls_begin(),
- RE = FD->redecls_end(); RI != RE; ++RI)
- if (RI->isInlineSpecified()) {
- Fn->addFnAttr(llvm::Attribute::InlineHint);
- break;
- }
+ if (!CGM.getCodeGenOpts().NoInline)
+ if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
+ for (FunctionDecl::redecl_iterator RI = FD->redecls_begin(),
+ RE = FD->redecls_end(); RI != RE; ++RI)
+ if (RI->isInlineSpecified()) {
+ Fn->addFnAttr(llvm::Attribute::InlineHint);
+ break;
+ }
- if (getContext().getLangOptions().OpenCL) {
+ if (getContext().getLangOpts().OpenCL) {
// Add metadata for a kernel function.
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
if (FD->hasAttr<OpenCLKernelAttr>()) {
@@ -340,7 +341,7 @@
// Tell the epilog emitter to autorelease the result. We do this
// now so that various specialized functions can suppress it
// during their IR-generation.
- if (getLangOptions().ObjCAutoRefCount &&
+ if (getLangOpts().ObjCAutoRefCount &&
!CurFnInfo->isReturnsRetained() &&
RetTy->isObjCRetainableType())
AutoreleaseResult = true;
@@ -442,7 +443,7 @@
EmitDestructorBody(Args);
else if (isa<CXXConstructorDecl>(FD))
EmitConstructorBody(Args);
- else if (getContext().getLangOptions().CUDA &&
+ else if (getContext().getLangOpts().CUDA &&
!CGM.getCodeGenOpts().CUDAIsDevice &&
FD->hasAttr<CUDAGlobalAttr>())
CGM.getCUDARuntime().EmitDeviceStubBody(*this, Args);
@@ -731,7 +732,7 @@
void
CodeGenFunction::EmitNullInitialization(llvm::Value *DestPtr, QualType Ty) {
// Ignore empty classes in C++.
- if (getContext().getLangOptions().CPlusPlus) {
+ if (getContext().getLangOpts().CPlusPlus) {
if (const RecordType *RT = Ty->getAs<RecordType>()) {
if (cast<CXXRecordDecl>(RT->getDecl())->isEmpty())
return;
Modified: cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h Mon Mar 19 14:02:20 2012
@@ -1210,7 +1210,7 @@
return CGM.getCodeGenOpts().OptimizationLevel == 0;
}
- const LangOptions &getLangOptions() const { return CGM.getLangOptions(); }
+ const LangOptions &getLangOpts() const { return CGM.getLangOpts(); }
/// Returns a pointer to the function's exception object and selector slot,
/// which is assigned in every landing pad.
@@ -1278,9 +1278,9 @@
return false;
case QualType::DK_cxx_destructor:
case QualType::DK_objc_weak_lifetime:
- return getLangOptions().Exceptions;
+ return getLangOpts().Exceptions;
case QualType::DK_objc_strong_lifetime:
- return getLangOptions().Exceptions &&
+ return getLangOpts().Exceptions &&
CGM.getCodeGenOpts().ObjCAutoRefCountExceptions;
}
llvm_unreachable("bad destruction kind");
@@ -1359,10 +1359,7 @@
}
void AllocateBlockCXXThisPointer(const CXXThisExpr *E);
- void AllocateBlockDecl(const BlockDeclRefExpr *E);
- llvm::Value *GetAddrOfBlockDecl(const BlockDeclRefExpr *E) {
- return GetAddrOfBlockDecl(E->getDecl(), E->isByRef());
- }
+ void AllocateBlockDecl(const DeclRefExpr *E);
llvm::Value *GetAddrOfBlockDecl(const VarDecl *var, bool ByRef);
llvm::Type *BuildByRefType(const VarDecl *var);
@@ -2107,6 +2104,36 @@
LValue EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E);
LValue EmitOpaqueValueLValue(const OpaqueValueExpr *e);
+ class ConstantEmission {
+ llvm::PointerIntPair<llvm::Constant*, 1, bool> ValueAndIsReference;
+ ConstantEmission(llvm::Constant *C, bool isReference)
+ : ValueAndIsReference(C, isReference) {}
+ public:
+ ConstantEmission() {}
+ static ConstantEmission forReference(llvm::Constant *C) {
+ return ConstantEmission(C, true);
+ }
+ static ConstantEmission forValue(llvm::Constant *C) {
+ return ConstantEmission(C, false);
+ }
+
+ operator bool() const { return ValueAndIsReference.getOpaqueValue() != 0; }
+
+ bool isReference() const { return ValueAndIsReference.getInt(); }
+ LValue getReferenceLValue(CodeGenFunction &CGF, Expr *refExpr) const {
+ assert(isReference());
+ return CGF.MakeNaturalAlignAddrLValue(ValueAndIsReference.getPointer(),
+ refExpr->getType());
+ }
+
+ llvm::Constant *getValue() const {
+ assert(!isReference());
+ return ValueAndIsReference.getPointer();
+ }
+ };
+
+ ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr);
+
RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e,
AggValueSlot slot = AggValueSlot::ignored());
LValue EmitPseudoObjectLValue(const PseudoObjectExpr *e);
@@ -2133,8 +2160,6 @@
LValue EmitLValueForBitfield(llvm::Value* Base, const FieldDecl* Field,
unsigned CVRQualifiers);
- LValue EmitBlockDeclRefLValue(const BlockDeclRefExpr *E);
-
LValue EmitCXXConstructLValue(const CXXConstructExpr *E);
LValue EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E);
LValue EmitLambdaLValue(const LambdaExpr *E);
Modified: cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp Mon Mar 19 14:02:20 2012
@@ -64,7 +64,7 @@
CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO,
llvm::Module &M, const llvm::TargetData &TD,
DiagnosticsEngine &diags)
- : Context(C), Features(C.getLangOptions()), CodeGenOpts(CGO), TheModule(M),
+ : Context(C), LangOpts(C.getLangOpts()), CodeGenOpts(CGO), TheModule(M),
TheTargetData(TD), TheTargetCodeGenInfo(0), Diags(diags),
ABI(createCXXABI(*this)),
Types(*this),
@@ -95,16 +95,16 @@
Int8PtrTy = Int8Ty->getPointerTo(0);
Int8PtrPtrTy = Int8PtrTy->getPointerTo(0);
- if (Features.ObjC1)
+ if (LangOpts.ObjC1)
createObjCRuntime();
- if (Features.OpenCL)
+ if (LangOpts.OpenCL)
createOpenCLRuntime();
- if (Features.CUDA)
+ if (LangOpts.CUDA)
createCUDARuntime();
// Enable TBAA unless it's suppressed.
if (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0)
- TBAA = new CodeGenTBAA(Context, VMContext, getLangOptions(),
+ TBAA = new CodeGenTBAA(Context, VMContext, getLangOpts(),
ABI.getMangleContext());
// If debug info or coverage generation is enabled, create the CGDebugInfo
@@ -115,7 +115,7 @@
Block.GlobalUniqueCount = 0;
- if (C.getLangOptions().ObjCAutoRefCount)
+ if (C.getLangOpts().ObjCAutoRefCount)
ARCData = new ARCEntrypoints();
RRData = new RREntrypoints();
}
@@ -133,7 +133,7 @@
}
void CodeGenModule::createObjCRuntime() {
- if (!Features.NeXTRuntime)
+ if (!LangOpts.NeXTRuntime)
ObjCRuntime = CreateGNUObjCRuntime(*this);
else
ObjCRuntime = CreateMacObjCRuntime(*this);
@@ -296,7 +296,7 @@
// If there's a key function, there may be translation units
// that don't have the key function's definition. But ignore
// this if we're emitting RTTI under -fno-rtti.
- if (!(TVK != TVK_ForRTTI) || Features.RTTI) {
+ if (!(TVK != TVK_ForRTTI) || LangOpts.RTTI) {
if (Context.getKeyFunction(RD))
return;
}
@@ -434,7 +434,7 @@
// merged with other definitions. c) C++ has the ODR, so we know the
// definition is dependable.
if (Linkage == GVA_CXXInline || Linkage == GVA_TemplateInstantiation)
- return !Context.getLangOptions().AppleKext
+ return !Context.getLangOpts().AppleKext
? llvm::Function::LinkOnceODRLinkage
: llvm::Function::InternalLinkage;
@@ -443,7 +443,7 @@
// and must all be equivalent. However, we are not allowed to
// throw away these explicit instantiations.
if (Linkage == GVA_ExplicitTemplateInstantiation)
- return !Context.getLangOptions().AppleKext
+ return !Context.getLangOpts().AppleKext
? llvm::Function::WeakODRLinkage
: llvm::Function::ExternalLinkage;
@@ -478,16 +478,16 @@
/// except under the fragile ObjC ABI with only ObjC exceptions
/// enabled. This means, for example, that C with -fexceptions
/// enables this.
-static bool hasUnwindExceptions(const LangOptions &Features) {
+static bool hasUnwindExceptions(const LangOptions &LangOpts) {
// If exceptions are completely disabled, obviously this is false.
- if (!Features.Exceptions) return false;
+ if (!LangOpts.Exceptions) return false;
// If C++ exceptions are enabled, this is true.
- if (Features.CXXExceptions) return true;
+ if (LangOpts.CXXExceptions) return true;
// If ObjC exceptions are enabled, this depends on the ABI.
- if (Features.ObjCExceptions) {
- if (!Features.ObjCNonFragileABI) return false;
+ if (LangOpts.ObjCExceptions) {
+ if (!LangOpts.ObjCNonFragileABI) return false;
}
return true;
@@ -498,7 +498,7 @@
if (CodeGenOpts.UnwindTables)
F->setHasUWTable();
- if (!hasUnwindExceptions(Features))
+ if (!hasUnwindExceptions(LangOpts))
F->addFnAttr(llvm::Attribute::NoUnwind);
if (D->hasAttr<NakedAttr>()) {
@@ -518,12 +518,12 @@
if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D))
F->setUnnamedAddr(true);
- if (Features.getStackProtector() == LangOptions::SSPOn)
+ if (LangOpts.getStackProtector() == LangOptions::SSPOn)
F->addFnAttr(llvm::Attribute::StackProtect);
- else if (Features.getStackProtector() == LangOptions::SSPReq)
+ else if (LangOpts.getStackProtector() == LangOptions::SSPReq)
F->addFnAttr(llvm::Attribute::StackProtectReq);
- if (Features.AddressSanitizer) {
+ if (LangOpts.AddressSanitizer) {
// When AddressSanitizer is enabled, set AddressSafety attribute
// unless __attribute__((no_address_safety_analysis)) is used.
if (!D->hasAttr<NoAddressSafetyAnalysisAttr>())
@@ -752,7 +752,7 @@
bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
// Never defer when EmitAllDecls is specified.
- if (Features.EmitAllDecls)
+ if (LangOpts.EmitAllDecls)
return false;
return !getContext().DeclMustBeEmitted(Global);
@@ -796,7 +796,7 @@
return EmitAliasDefinition(GD);
// If this is CUDA, be selective about which declarations we emit.
- if (Features.CUDA) {
+ if (LangOpts.CUDA) {
if (CodeGenOpts.CUDAIsDevice) {
if (!Global->hasAttr<CUDADeviceAttr>() &&
!Global->hasAttr<CUDAGlobalAttr>() &&
@@ -848,7 +848,7 @@
// If we're deferring emission of a C++ variable with an
// initializer, remember the order in which it appeared in the file.
- if (getLangOptions().CPlusPlus && isa<VarDecl>(Global) &&
+ if (getLangOpts().CPlusPlus && isa<VarDecl>(Global) &&
cast<VarDecl>(Global)->hasInit()) {
DelayedCXXInitPosition[Global] = CXXGlobalInits.size();
CXXGlobalInits.push_back(0);
@@ -1048,7 +1048,7 @@
//
// We also don't emit a definition for a function if it's going to be an entry
// in a vtable, unless it's already marked as used.
- } else if (getLangOptions().CPlusPlus && D.getDecl()) {
+ } else if (getLangOpts().CPlusPlus && D.getDecl()) {
// Look for a declaration that's lexically in a record.
const FunctionDecl *FD = cast<FunctionDecl>(D.getDecl());
do {
@@ -1110,7 +1110,7 @@
if (!Ty.isConstant(Context) && !Ty->isReferenceType())
return false;
- if (Context.getLangOptions().CPlusPlus) {
+ if (Context.getLangOpts().CPlusPlus) {
if (const CXXRecordDecl *Record
= Context.getBaseElementType(Ty)->getAsCXXRecordDecl())
return ExcludeCtor && !Record->hasMutableFields() &&
@@ -1309,19 +1309,19 @@
return llvm::GlobalVariable::AvailableExternallyLinkage;
if (KeyFunction->isInlined())
- return !Context.getLangOptions().AppleKext ?
+ return !Context.getLangOpts().AppleKext ?
llvm::GlobalVariable::LinkOnceODRLinkage :
llvm::Function::InternalLinkage;
return llvm::GlobalVariable::ExternalLinkage;
case TSK_ImplicitInstantiation:
- return !Context.getLangOptions().AppleKext ?
+ return !Context.getLangOpts().AppleKext ?
llvm::GlobalVariable::LinkOnceODRLinkage :
llvm::Function::InternalLinkage;
case TSK_ExplicitInstantiationDefinition:
- return !Context.getLangOptions().AppleKext ?
+ return !Context.getLangOpts().AppleKext ?
llvm::GlobalVariable::WeakODRLinkage :
llvm::Function::InternalLinkage;
@@ -1329,13 +1329,13 @@
// FIXME: Use available_externally linkage. However, this currently
// breaks LLVM's build due to undefined symbols.
// return llvm::GlobalVariable::AvailableExternallyLinkage;
- return !Context.getLangOptions().AppleKext ?
+ return !Context.getLangOpts().AppleKext ?
llvm::GlobalVariable::LinkOnceODRLinkage :
llvm::Function::InternalLinkage;
}
}
- if (Context.getLangOptions().AppleKext)
+ if (Context.getLangOpts().AppleKext)
return llvm::Function::InternalLinkage;
switch (RD->getTemplateSpecializationKind()) {
@@ -1515,7 +1515,7 @@
if (D->getType()->isReferenceType())
T = D->getType();
- if (getLangOptions().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
Init = EmitNullConstant(T);
NeedsGlobalCtor = true;
} else {
@@ -1526,7 +1526,7 @@
// We don't need an initializer, so remove the entry for the delayed
// initializer position (just in case this entry was delayed) if we
// also don't need to register a destructor.
- if (getLangOptions().CPlusPlus && !NeedsGlobalDtor)
+ if (getLangOpts().CPlusPlus && !NeedsGlobalDtor)
DelayedCXXInitPosition.erase(D);
}
}
@@ -1622,7 +1622,7 @@
} else if (Linkage == GVA_TemplateInstantiation ||
Linkage == GVA_ExplicitTemplateInstantiation)
return llvm::GlobalVariable::WeakODRLinkage;
- else if (!getLangOptions().CPlusPlus &&
+ else if (!getLangOpts().CPlusPlus &&
((!CodeGenOpts.NoCommon && !D->getAttr<NoCommonAttr>()) ||
D->getAttr<CommonAttr>()) &&
!D->hasExternalStorage() && !D->getInit() &&
@@ -2036,7 +2036,7 @@
CreateRecordDecl(const ASTContext &Ctx, RecordDecl::TagKind TK,
DeclContext *DC, IdentifierInfo *Id) {
SourceLocation Loc;
- if (Ctx.getLangOptions().CPlusPlus)
+ if (Ctx.getLangOpts().CPlusPlus)
return CXXRecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id);
else
return RecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id);
@@ -2056,10 +2056,10 @@
// If we don't already have it, get _NSConstantStringClassReference.
if (!ConstantStringClassRef) {
- std::string StringClass(getLangOptions().ObjCConstantStringClass);
+ std::string StringClass(getLangOpts().ObjCConstantStringClass);
llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy);
llvm::Constant *GV;
- if (Features.ObjCNonFragileABI) {
+ if (LangOpts.ObjCNonFragileABI) {
std::string str =
StringClass.empty() ? "OBJC_CLASS_$_NSConstantString"
: "OBJC_CLASS_$_" + StringClass;
@@ -2126,7 +2126,7 @@
llvm::GlobalValue::LinkageTypes Linkage;
bool isConstant;
Linkage = llvm::GlobalValue::PrivateLinkage;
- isConstant = !Features.WritableStrings;
+ isConstant = !LangOpts.WritableStrings;
llvm::GlobalVariable *GV =
new llvm::GlobalVariable(getModule(), C->getType(), isConstant, Linkage, C,
@@ -2147,7 +2147,7 @@
"_unnamed_nsstring_");
// FIXME. Fix section.
if (const char *Sect =
- Features.ObjCNonFragileABI
+ LangOpts.ObjCNonFragileABI
? getContext().getTargetInfo().getNSStringNonFragileABISection()
: getContext().getTargetInfo().getNSStringSection())
GV->setSection(Sect);
@@ -2250,7 +2250,7 @@
llvm::Constant *C = GetConstantArrayFromStringLiteral(S);
llvm::GlobalVariable *GV =
new llvm::GlobalVariable(getModule(),C->getType(),
- !Features.WritableStrings,
+ !LangOpts.WritableStrings,
llvm::GlobalValue::PrivateLinkage,
C,".str");
@@ -2306,7 +2306,7 @@
GlobalName = ".str";
// Don't share any string literals if strings aren't constant.
- if (Features.WritableStrings)
+ if (LangOpts.WritableStrings)
return GenerateStringLiteral(Str, false, *this, GlobalName, Alignment);
llvm::StringMapEntry<llvm::GlobalVariable *> &Entry =
@@ -2530,7 +2530,7 @@
case Decl::ObjCImplementation: {
ObjCImplementationDecl *OMD = cast<ObjCImplementationDecl>(D);
- if (Features.ObjCNonFragileABI2 && OMD->hasSynthBitfield())
+ if (LangOpts.ObjCNonFragileABI2 && OMD->hasSynthBitfield())
Context.ResetObjCLayout(OMD->getClassInterface());
EmitObjCPropertyImplementations(OMD);
EmitObjCIvarInitializations(OMD);
Modified: cfe/branches/tooling/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenModule.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenModule.h Mon Mar 19 14:02:20 2012
@@ -215,7 +215,7 @@
typedef std::vector<std::pair<llvm::Constant*, int> > CtorList;
ASTContext &Context;
- const LangOptions &Features;
+ const LangOptions &LangOpts;
const CodeGenOptions &CodeGenOpts;
llvm::Module &TheModule;
const llvm::TargetData &TheTargetData;
@@ -279,7 +279,7 @@
llvm::StringMap<llvm::Constant*> CFConstantStringMap;
llvm::StringMap<llvm::GlobalVariable*> ConstantStringMap;
- llvm::DenseMap<const Decl*, llvm::Value*> StaticLocalDeclMap;
+ llvm::DenseMap<const Decl*, llvm::Constant *> StaticLocalDeclMap;
llvm::DenseMap<QualType, llvm::Constant *> AtomicSetterHelperFnMap;
llvm::DenseMap<QualType, llvm::Constant *> AtomicGetterHelperFnMap;
@@ -388,7 +388,7 @@
CGCXXABI &getCXXABI() { return ABI; }
ARCEntrypoints &getARCEntrypoints() const {
- assert(getLangOptions().ObjCAutoRefCount && ARCData != 0);
+ assert(getLangOpts().ObjCAutoRefCount && ARCData != 0);
return *ARCData;
}
@@ -397,12 +397,12 @@
return *RRData;
}
- llvm::Value *getStaticLocalDeclAddress(const VarDecl *VD) {
- return StaticLocalDeclMap[VD];
+ llvm::Constant *getStaticLocalDeclAddress(const VarDecl *D) {
+ return StaticLocalDeclMap[D];
}
void setStaticLocalDeclAddress(const VarDecl *D,
- llvm::GlobalVariable *GV) {
- StaticLocalDeclMap[D] = GV;
+ llvm::Constant *C) {
+ StaticLocalDeclMap[D] = C;
}
llvm::Constant *getAtomicSetterHelperFnMap(QualType Ty) {
@@ -433,7 +433,7 @@
ASTContext &getContext() const { return Context; }
const CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; }
- const LangOptions &getLangOptions() const { return Features; }
+ const LangOptions &getLangOpts() const { return LangOpts; }
llvm::Module &getModule() const { return TheModule; }
CodeGenTypes &getTypes() { return Types; }
CodeGenVTables &getVTables() { return VTables; }
Modified: cfe/branches/tooling/lib/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenTypes.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenTypes.cpp Mon Mar 19 14:02:20 2012
@@ -651,7 +651,7 @@
bool CodeGenTypes::isZeroInitializable(QualType T) {
// No need to check for member pointers when not compiling C++.
- if (!Context.getLangOptions().CPlusPlus)
+ if (!Context.getLangOpts().CPlusPlus)
return true;
T = Context.getBaseElementType(T);
Modified: cfe/branches/tooling/lib/CodeGen/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/ItaniumCXXABI.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/ItaniumCXXABI.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/ItaniumCXXABI.cpp Mon Mar 19 14:02:20 2012
@@ -805,7 +805,7 @@
// Automatic Reference Counting:
// We need an array cookie for pointers with strong or weak lifetime.
QualType AllocatedType = expr->getAllocatedType();
- if (getContext().getLangOptions().ObjCAutoRefCount &&
+ if (getContext().getLangOpts().ObjCAutoRefCount &&
AllocatedType->isObjCLifetimeType()) {
switch (AllocatedType.getObjCLifetime()) {
case Qualifiers::OCL_None:
@@ -1071,7 +1071,7 @@
// We only need to use thread-safe statics for local variables;
// global initialization is always single-threaded.
bool threadsafe =
- (getContext().getLangOptions().ThreadsafeStatics && D.isLocalVarDecl());
+ (getContext().getLangOpts().ThreadsafeStatics && D.isLocalVarDecl());
llvm::IntegerType *GuardTy;
Modified: cfe/branches/tooling/lib/CodeGen/ModuleBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/ModuleBuilder.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/ModuleBuilder.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/ModuleBuilder.cpp Mon Mar 19 14:02:20 2012
@@ -79,7 +79,7 @@
// In C++, we may have member functions that need to be emitted at this
// point.
- if (Ctx->getLangOptions().CPlusPlus && !D->isDependentContext()) {
+ if (Ctx->getLangOpts().CPlusPlus && !D->isDependentContext()) {
for (DeclContext::decl_iterator M = D->decls_begin(),
MEnd = D->decls_end();
M != MEnd; ++M)
Modified: cfe/branches/tooling/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/TargetInfo.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/TargetInfo.cpp Mon Mar 19 14:02:20 2012
@@ -924,11 +924,15 @@
/// getIndirectResult - Give a source type \arg Ty, return a suitable result
/// such that the argument will be passed in memory.
- ABIArgInfo getIndirectResult(QualType Ty) const;
+ ///
+ /// \param freeIntRegs - The number of free integer registers remaining
+ /// available.
+ ABIArgInfo getIndirectResult(QualType Ty, unsigned freeIntRegs) const;
ABIArgInfo classifyReturnType(QualType RetTy) const;
ABIArgInfo classifyArgumentType(QualType Ty,
+ unsigned freeIntRegs,
unsigned &neededInt,
unsigned &neededSSE) const;
@@ -951,7 +955,8 @@
bool isPassedUsingAVXType(QualType type) const {
unsigned neededInt, neededSSE;
- ABIArgInfo info = classifyArgumentType(type, neededInt, neededSSE);
+ // The freeIntRegs argument doesn't matter here.
+ ABIArgInfo info = classifyArgumentType(type, 0, neededInt, neededSSE);
if (info.isDirect()) {
llvm::Type *ty = info.getCoerceToType();
if (llvm::VectorType *vectorTy = dyn_cast_or_null<llvm::VectorType>(ty))
@@ -1441,9 +1446,16 @@
return false;
}
-ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty) const {
+ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty,
+ unsigned freeIntRegs) const {
// If this is a scalar LLVM value then assume LLVM will pass it in the right
// place naturally.
+ //
+ // This assumption is optimistic, as there could be free registers available
+ // when we need to pass this argument in memory, and LLVM could try to pass
+ // the argument in the free register. This does not seem to happen currently,
+ // but this code would be much safer if we could mark the argument with
+ // 'onstack'. See PR12193.
if (!isAggregateTypeForABI(Ty) && !IsIllegalVectorType(Ty)) {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
@@ -1459,6 +1471,38 @@
// Compute the byval alignment. We specify the alignment of the byval in all
// cases so that the mid-level optimizer knows the alignment of the byval.
unsigned Align = std::max(getContext().getTypeAlign(Ty) / 8, 8U);
+
+ // Attempt to avoid passing indirect results using byval when possible. This
+ // is important for good codegen.
+ //
+ // We do this by coercing the value into a scalar type which the backend can
+ // handle naturally (i.e., without using byval).
+ //
+ // For simplicity, we currently only do this when we have exhausted all of the
+ // free integer registers. Doing this when there are free integer registers
+ // would require more care, as we would have to ensure that the coerced value
+ // did not claim the unused register. That would require either reording the
+ // arguments to the function (so that any subsequent inreg values came first),
+ // or only doing this optimization when there were no following arguments that
+ // might be inreg.
+ //
+ // We currently expect it to be rare (particularly in well written code) for
+ // arguments to be passed on the stack when there are still free integer
+ // registers available (this would typically imply large structs being passed
+ // by value), so this seems like a fair tradeoff for now.
+ //
+ // We can revisit this if the backend grows support for 'onstack' parameter
+ // attributes. See PR12193.
+ if (freeIntRegs == 0) {
+ uint64_t Size = getContext().getTypeSize(Ty);
+
+ // If this type fits in an eightbyte, coerce it into the matching integral
+ // type, which will end up on the stack (with alignment 8).
+ if (Align == 8 && Size <= 64)
+ return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),
+ Size));
+ }
+
return ABIArgInfo::getIndirect(Align);
}
@@ -1874,8 +1918,10 @@
return ABIArgInfo::getDirect(ResType);
}
-ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned &neededInt,
- unsigned &neededSSE) const {
+ABIArgInfo X86_64ABIInfo::classifyArgumentType(
+ QualType Ty, unsigned freeIntRegs, unsigned &neededInt, unsigned &neededSSE)
+ const
+{
X86_64ABIInfo::Class Lo, Hi;
classify(Ty, 0, Lo, Hi);
@@ -1907,7 +1953,7 @@
case ComplexX87:
if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty))
++neededInt;
- return getIndirectResult(Ty);
+ return getIndirectResult(Ty, freeIntRegs);
case SSEUp:
case X87Up:
@@ -2015,7 +2061,8 @@
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
it != ie; ++it) {
unsigned neededInt, neededSSE;
- it->info = classifyArgumentType(it->type, neededInt, neededSSE);
+ it->info = classifyArgumentType(it->type, freeIntRegs, neededInt,
+ neededSSE);
// AMD64-ABI 3.2.3p3: If there are no registers available for any
// eightbyte of an argument, the whole argument is passed on the
@@ -2025,7 +2072,7 @@
freeIntRegs -= neededInt;
freeSSERegs -= neededSSE;
} else {
- it->info = getIndirectResult(it->type);
+ it->info = getIndirectResult(it->type, freeIntRegs);
}
}
}
@@ -2091,7 +2138,7 @@
unsigned neededInt, neededSSE;
Ty = CGF.getContext().getCanonicalType(Ty);
- ABIArgInfo AI = classifyArgumentType(Ty, neededInt, neededSSE);
+ ABIArgInfo AI = classifyArgumentType(Ty, 0, neededInt, neededSSE);
// AMD64-ABI 3.5.7p5: Step 1. Determine whether type may be passed
// in the registers. If not go to step 7.
@@ -2835,7 +2882,7 @@
// Calling convention as default by an ABI.
llvm::CallingConv::ID DefaultCC;
- const LangOptions &LangOpts = getContext().getLangOptions();
+ const LangOptions &LangOpts = getContext().getLangOpts();
if (LangOpts.OpenCL || LangOpts.CUDA) {
// If we are in OpenCL or CUDA mode, then default to device functions
DefaultCC = llvm::CallingConv::PTX_Device;
@@ -2866,7 +2913,7 @@
llvm::Function *F = cast<llvm::Function>(GV);
// Perform special handling in OpenCL mode
- if (M.getLangOptions().OpenCL) {
+ if (M.getLangOpts().OpenCL) {
// Use OpenCL function attributes to set proper calling conventions
// By default, all functions are device functions
if (FD->hasAttr<OpenCLKernelAttr>()) {
@@ -2878,7 +2925,7 @@
}
// Perform special handling in CUDA mode.
- if (M.getLangOptions().CUDA) {
+ if (M.getLangOpts().CUDA) {
// CUDA __global__ functions get a kernel calling convention. Since
// __global__ functions cannot be called from the device, we do not
// need to set the noinline attribute.
@@ -3373,7 +3420,7 @@
llvm::Function *F = cast<llvm::Function>(GV);
- if (M.getLangOptions().OpenCL) {
+ if (M.getLangOpts().OpenCL) {
if (FD->hasAttr<OpenCLKernelAttr>()) {
// OpenCL C Kernel functions are not subject to inlining
F->addFnAttr(llvm::Attribute::NoInline);
Modified: cfe/branches/tooling/lib/Driver/ArgList.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/ArgList.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/ArgList.cpp (original)
+++ cfe/branches/tooling/lib/Driver/ArgList.cpp Mon Mar 19 14:02:20 2012
@@ -154,13 +154,15 @@
}
int ArgList::getLastArgIntValue(OptSpecifier Id, int Default,
- clang::DiagnosticsEngine &Diags) const {
+ clang::DiagnosticsEngine *Diags) const {
int Res = Default;
if (Arg *A = getLastArg(Id)) {
- if (StringRef(A->getValue(*this)).getAsInteger(10, Res))
- Diags.Report(diag::err_drv_invalid_int_value)
- << A->getAsString(*this) << A->getValue(*this);
+ if (StringRef(A->getValue(*this)).getAsInteger(10, Res)) {
+ if (Diags)
+ Diags->Report(diag::err_drv_invalid_int_value)
+ << A->getAsString(*this) << A->getValue(*this);
+ }
}
return Res;
Modified: cfe/branches/tooling/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/Driver.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/Driver.cpp (original)
+++ cfe/branches/tooling/lib/Driver/Driver.cpp Mon Mar 19 14:02:20 2012
@@ -247,7 +247,7 @@
llvm::PrettyStackTraceString CrashInfo("Compilation construction");
// FIXME: Handle environment options which affect driver behavior, somewhere
- // (client?). GCC_EXEC_PREFIX, LIBRARY_PATH, LPATH, CC_PRINT_OPTIONS.
+ // (client?). GCC_EXEC_PREFIX, LPATH, CC_PRINT_OPTIONS.
if (char *env = ::getenv("COMPILER_PATH")) {
StringRef CompilerPath = env;
Modified: cfe/branches/tooling/lib/Driver/ToolChains.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/ToolChains.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/ToolChains.cpp (original)
+++ cfe/branches/tooling/lib/Driver/ToolChains.cpp Mon Mar 19 14:02:20 2012
@@ -182,14 +182,10 @@
if (!isTargetInitialized())
return Triple.getTriple();
- unsigned Version[3];
- getTargetVersion(Version);
-
SmallString<16> Str;
- llvm::raw_svector_ostream(Str)
- << (isTargetIPhoneOS() ? "ios" : "macosx")
- << Version[0] << "." << Version[1] << "." << Version[2];
- Triple.setOSName(Str.str());
+ Str += isTargetIPhoneOS() ? "ios" : "macosx";
+ Str += getTargetVersion().getAsString();
+ Triple.setOSName(Str);
return Triple.getTriple();
}
Modified: cfe/branches/tooling/lib/Driver/ToolChains.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/ToolChains.h?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/ToolChains.h (original)
+++ cfe/branches/tooling/lib/Driver/ToolChains.h Mon Mar 19 14:02:20 2012
@@ -13,6 +13,7 @@
#include "clang/Driver/Action.h"
#include "clang/Driver/ToolChain.h"
+#include "clang/Basic/VersionTuple.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Compiler.h"
@@ -198,7 +199,7 @@
mutable bool TargetIsIPhoneOSSimulator;
/// The OS version we are targeting.
- mutable unsigned TargetVersion[3];
+ mutable VersionTuple TargetVersion;
/// The default macosx-version-min of this tool chain; empty until
/// initialized.
@@ -230,17 +231,14 @@
// change. This will go away when we move away from argument translation.
if (TargetInitialized && TargetIsIPhoneOS == IsIPhoneOS &&
TargetIsIPhoneOSSimulator == IsIOSSim &&
- TargetVersion[0] == Major && TargetVersion[1] == Minor &&
- TargetVersion[2] == Micro)
+ TargetVersion == VersionTuple(Major, Minor, Micro))
return;
assert(!TargetInitialized && "Target already initialized!");
TargetInitialized = true;
TargetIsIPhoneOS = IsIPhoneOS;
TargetIsIPhoneOSSimulator = IsIOSSim;
- TargetVersion[0] = Major;
- TargetVersion[1] = Minor;
- TargetVersion[2] = Micro;
+ TargetVersion = VersionTuple(Major, Minor, Micro);
}
bool isTargetIPhoneOS() const {
@@ -261,11 +259,9 @@
bool isTargetInitialized() const { return TargetInitialized; }
- void getTargetVersion(unsigned (&Res)[3]) const {
+ VersionTuple getTargetVersion() const {
assert(TargetInitialized && "Target not initialized!");
- Res[0] = TargetVersion[0];
- Res[1] = TargetVersion[1];
- Res[2] = TargetVersion[2];
+ return TargetVersion;
}
/// getDarwinArchName - Get the "Darwin" arch name for a particular compiler
@@ -273,24 +269,14 @@
/// distinct architectures.
StringRef getDarwinArchName(const ArgList &Args) const;
- static bool isVersionLT(unsigned (&A)[3], unsigned (&B)[3]) {
- for (unsigned i=0; i < 3; ++i) {
- if (A[i] > B[i]) return false;
- if (A[i] < B[i]) return true;
- }
- return false;
- }
-
bool isIPhoneOSVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const {
assert(isTargetIPhoneOS() && "Unexpected call for OS X target!");
- unsigned B[3] = { V0, V1, V2 };
- return isVersionLT(TargetVersion, B);
+ return TargetVersion < VersionTuple(V0, V1, V2);
}
bool isMacosxVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const {
assert(!isTargetIPhoneOS() && "Unexpected call for iPhoneOS target!");
- unsigned B[3] = { V0, V1, V2 };
- return isVersionLT(TargetVersion, B);
+ return TargetVersion < VersionTuple(V0, V1, V2);
}
/// AddLinkSearchPathArgs - Add the linker search paths to \arg CmdArgs.
Modified: cfe/branches/tooling/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/Tools.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/Tools.cpp (original)
+++ cfe/branches/tooling/lib/Driver/Tools.cpp Mon Mar 19 14:02:20 2012
@@ -88,6 +88,39 @@
}
}
+static void addDirectoryList(const ArgList &Args,
+ ArgStringList &CmdArgs,
+ const char *ArgName,
+ const char *EnvVar) {
+ const char *DirList = ::getenv(EnvVar);
+ if (!DirList)
+ return; // Nothing to do.
+
+ StringRef Dirs(DirList);
+ if (Dirs.empty()) // Empty string should not add '.'.
+ return;
+
+ StringRef::size_type Delim;
+ while ((Delim = Dirs.find(llvm::sys::PathSeparator)) != StringRef::npos) {
+ if (Delim == 0) { // Leading colon.
+ CmdArgs.push_back(ArgName);
+ CmdArgs.push_back(".");
+ } else {
+ CmdArgs.push_back(ArgName);
+ CmdArgs.push_back(Args.MakeArgString(Dirs.substr(0, Delim)));
+ }
+ Dirs = Dirs.substr(Delim + 1);
+ }
+
+ if (Dirs.empty()) { // Trailing colon.
+ CmdArgs.push_back(ArgName);
+ CmdArgs.push_back(".");
+ } else { // Add the last path.
+ CmdArgs.push_back(ArgName);
+ CmdArgs.push_back(Args.MakeArgString(Dirs));
+ }
+}
+
static void AddLinkerInputs(const ToolChain &TC,
const InputInfoList &Inputs, const ArgList &Args,
ArgStringList &CmdArgs) {
@@ -128,6 +161,9 @@
} else
A.renderAsInput(Args, CmdArgs);
}
+
+ // LIBRARY_PATH - included following the user specified library paths.
+ addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH");
}
/// \brief Determine whether Objective-C automated reference counting is
@@ -162,38 +198,6 @@
CmdArgs.push_back(Args.MakeArgString(ProfileRT));
}
-static void AddIncludeDirectoryList(const ArgList &Args,
- ArgStringList &CmdArgs,
- const char *ArgName,
- const char *DirList) {
- if (!DirList)
- return; // Nothing to do.
-
- StringRef Dirs(DirList);
- if (Dirs.empty()) // Empty string should not add '.'.
- return;
-
- StringRef::size_type Delim;
- while ((Delim = Dirs.find(llvm::sys::PathSeparator)) != StringRef::npos) {
- if (Delim == 0) { // Leading colon.
- CmdArgs.push_back(ArgName);
- CmdArgs.push_back(".");
- } else {
- CmdArgs.push_back(ArgName);
- CmdArgs.push_back(Args.MakeArgString(Dirs.substr(0, Delim)));
- }
- Dirs = Dirs.substr(Delim + 1);
- }
-
- if (Dirs.empty()) { // Trailing colon.
- CmdArgs.push_back(ArgName);
- CmdArgs.push_back(".");
- } else { // Add the last path.
- CmdArgs.push_back(ArgName);
- CmdArgs.push_back(Args.MakeArgString(Dirs));
- }
-}
-
void Clang::AddPreprocessingOptions(Compilation &C,
const Driver &D,
const ArgList &Args,
@@ -399,19 +403,15 @@
// frontend into the driver. It will allow deleting 4 otherwise unused flags.
// CPATH - included following the user specified includes (but prior to
// builtin and standard includes).
- AddIncludeDirectoryList(Args, CmdArgs, "-I", ::getenv("CPATH"));
+ addDirectoryList(Args, CmdArgs, "-I", "CPATH");
// C_INCLUDE_PATH - system includes enabled when compiling C.
- AddIncludeDirectoryList(Args, CmdArgs, "-c-isystem",
- ::getenv("C_INCLUDE_PATH"));
+ addDirectoryList(Args, CmdArgs, "-c-isystem", "C_INCLUDE_PATH");
// CPLUS_INCLUDE_PATH - system includes enabled when compiling C++.
- AddIncludeDirectoryList(Args, CmdArgs, "-cxx-isystem",
- ::getenv("CPLUS_INCLUDE_PATH"));
+ addDirectoryList(Args, CmdArgs, "-cxx-isystem", "CPLUS_INCLUDE_PATH");
// OBJC_INCLUDE_PATH - system includes enabled when compiling ObjC.
- AddIncludeDirectoryList(Args, CmdArgs, "-objc-isystem",
- ::getenv("OBJC_INCLUDE_PATH"));
+ addDirectoryList(Args, CmdArgs, "-objc-isystem", "OBJC_INCLUDE_PATH");
// OBJCPLUS_INCLUDE_PATH - system includes enabled when compiling ObjC++.
- AddIncludeDirectoryList(Args, CmdArgs, "-objcxx-isystem",
- ::getenv("OBJCPLUS_INCLUDE_PATH"));
+ addDirectoryList(Args, CmdArgs, "-objcxx-isystem", "OBJCPLUS_INCLUDE_PATH");
// Add C++ include arguments, if needed.
if (types::isCXX(Inputs[0].getType()))
@@ -1345,7 +1345,7 @@
CmdArgs.push_back("-analyzer-eagerly-assume");
- CmdArgs.push_back("-analyzer-inline-call");
+ CmdArgs.push_back("-analyzer-ipa=inlining");
// Add default argument set.
if (!Args.hasArg(options::OPT__analyzer_no_default_checks)) {
@@ -1950,6 +1950,14 @@
Args.AddLastArg(CmdArgs, options::OPT_fno_limit_debug_info);
Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names);
Args.AddLastArg(CmdArgs, options::OPT_faltivec);
+
+ // Report and error for -faltivec on anything other then PowerPC.
+ if (const Arg *A = Args.getLastArg(options::OPT_faltivec))
+ if (!(getToolChain().getTriple().getArch() == llvm::Triple::ppc ||
+ getToolChain().getTriple().getArch() == llvm::Triple::ppc64))
+ D.Diag(diag::err_drv_argument_only_allowed_with)
+ << A->getAsString(Args) << "ppc/ppc64";
+
if (getToolChain().SupportsProfiling())
Args.AddLastArg(CmdArgs, options::OPT_pg);
@@ -2165,6 +2173,9 @@
false))
CmdArgs.push_back("-fgnu89-inline");
+ if (Args.hasArg(options::OPT_fno_inline))
+ CmdArgs.push_back("-fno-inline");
+
if (Args.hasArg(options::OPT_fno_inline_functions))
CmdArgs.push_back("-fno-inline-functions");
@@ -2250,7 +2261,8 @@
}
}
- // -fobjc-default-synthesize-properties=0 is default.
+ // -fobjc-default-synthesize-properties=1 is default. This only has an effect
+ // if the nonfragile objc abi is used.
if (Args.hasFlag(options::OPT_fobjc_default_synthesize_properties,
options::OPT_fno_objc_default_synthesize_properties,
getToolChain().IsObjCDefaultSynthPropertiesDefault())) {
@@ -3159,6 +3171,7 @@
.Case("c++11-narrowing", true)
.Case("conditional-uninitialized", true)
.Case("constant-conversion", true)
+ .Case("conversion-null", true)
.Case("CFString-literal", true)
.Case("constant-logical-operand", true)
.Case("custom-atomic-properties", true)
@@ -3851,8 +3864,7 @@
Args.AddAllArgs(CmdArgs, options::OPT_init);
// Add the deployment target.
- unsigned TargetVersion[3];
- DarwinTC.getTargetVersion(TargetVersion);
+ VersionTuple TargetVersion = DarwinTC.getTargetVersion();
// If we had an explicit -mios-simulator-version-min argument, honor that,
// otherwise use the traditional deployment targets. We can't just check the
@@ -3867,9 +3879,7 @@
CmdArgs.push_back("-iphoneos_version_min");
else
CmdArgs.push_back("-macosx_version_min");
- CmdArgs.push_back(Args.MakeArgString(Twine(TargetVersion[0]) + "." +
- Twine(TargetVersion[1]) + "." +
- Twine(TargetVersion[2])));
+ CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);
Args.AddLastArg(CmdArgs, options::OPT_multi__module);
@@ -4303,11 +4313,12 @@
CmdArgs.push_back(Args.MakeArgString(LibPath + "values-Xa.o"));
CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o"));
} else {
- CmdArgs.push_back(Args.MakeArgString(LibPath + "cxa_finalize.o"));
CmdArgs.push_back(Args.MakeArgString(LibPath + "crti.o"));
CmdArgs.push_back(Args.MakeArgString(LibPath + "values-Xa.o"));
CmdArgs.push_back(Args.MakeArgString(GCCLibPath + "crtbegin.o"));
}
+ if (getToolChain().getDriver().CCCIsCXX)
+ CmdArgs.push_back(Args.MakeArgString(LibPath + "cxa_finalize.o"));
}
CmdArgs.push_back(Args.MakeArgString("-L" + GCCLibPath));
Modified: cfe/branches/tooling/lib/Driver/WindowsToolChain.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/WindowsToolChain.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/WindowsToolChain.cpp (original)
+++ cfe/branches/tooling/lib/Driver/WindowsToolChain.cpp Mon Mar 19 14:02:20 2012
@@ -318,10 +318,26 @@
if (DriverArgs.hasArg(options::OPT_nostdlibinc))
return;
+#ifdef _MSC_VER
+ // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
+ if (const char *cl_include_dir = getenv("INCLUDE")) {
+ SmallVector<StringRef, 8> Dirs;
+ StringRef(cl_include_dir).split(Dirs, ";");
+ int n = 0;
+ for (SmallVectorImpl<StringRef>::iterator I = Dirs.begin(), E = Dirs.end();
+ I != E; ++I) {
+ StringRef d = *I;
+ if (d.size() == 0)
+ continue;
+ ++n;
+ addSystemInclude(DriverArgs, CC1Args, d);
+ }
+ if (n) return;
+ }
+
std::string VSDir;
std::string WindowsSDKDir;
-#ifdef _MSC_VER
// When built with access to the proper Windows APIs, try to actually find
// the correct include paths first.
if (getVisualStudioDir(VSDir)) {
Modified: cfe/branches/tooling/lib/Edit/Commit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Edit/Commit.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Edit/Commit.cpp (original)
+++ cfe/branches/tooling/lib/Edit/Commit.cpp Mon Mar 19 14:02:20 2012
@@ -36,7 +36,7 @@
}
Commit::Commit(EditedSource &Editor)
- : SourceMgr(Editor.getSourceManager()), LangOpts(Editor.getLangOptions()),
+ : SourceMgr(Editor.getSourceManager()), LangOpts(Editor.getLangOpts()),
PPRec(Editor.getPreprocessingRecord()),
Editor(&Editor), IsCommitable(true) { }
Modified: cfe/branches/tooling/lib/Edit/RewriteObjCFoundationAPI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Edit/RewriteObjCFoundationAPI.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Edit/RewriteObjCFoundationAPI.cpp (original)
+++ cfe/branches/tooling/lib/Edit/RewriteObjCFoundationAPI.cpp Mon Mar 19 14:02:20 2012
@@ -392,7 +392,7 @@
return false;
StringRef text = Lexer::getSourceText(
CharSourceRange::getTokenRange(literalRange),
- Ctx.getSourceManager(), Ctx.getLangOptions());
+ Ctx.getSourceManager(), Ctx.getLangOpts());
if (text.empty())
return false;
@@ -486,8 +486,7 @@
return false;
NSAPI::NSNumberLiteralMethodKind MK = *MKOpt;
- bool CallIsInteger = false, CallIsUnsigned = false;
- bool CallIsLong = false, CallIsLongLong = false;
+ bool CallIsUnsigned = false, CallIsLong = false, CallIsLongLong = false;
bool CallIsFloating = false, CallIsDouble = false;
switch (MK) {
@@ -504,19 +503,18 @@
CallIsUnsigned = true;
case NSAPI::NSNumberWithInt:
case NSAPI::NSNumberWithInteger:
- CallIsInteger = true;
break;
case NSAPI::NSNumberWithUnsignedLong:
CallIsUnsigned = true;
case NSAPI::NSNumberWithLong:
- CallIsInteger = true; CallIsLong = true;
+ CallIsLong = true;
break;
case NSAPI::NSNumberWithUnsignedLongLong:
CallIsUnsigned = true;
case NSAPI::NSNumberWithLongLong:
- CallIsInteger = true; CallIsLongLong = true;
+ CallIsLongLong = true;
break;
case NSAPI::NSNumberWithDouble:
Modified: cfe/branches/tooling/lib/Frontend/ASTMerge.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/ASTMerge.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/ASTMerge.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/ASTMerge.cpp Mon Mar 19 14:02:20 2012
@@ -34,7 +34,7 @@
void ASTMergeAction::ExecuteAction() {
CompilerInstance &CI = getCompilerInstance();
CI.getDiagnostics().getClient()->BeginSourceFile(
- CI.getASTContext().getLangOptions());
+ CI.getASTContext().getLangOpts());
CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument,
&CI.getASTContext());
IntrusiveRefCntPtr<DiagnosticIDs>
Modified: cfe/branches/tooling/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/ASTUnit.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/ASTUnit.cpp Mon Mar 19 14:02:20 2012
@@ -364,7 +364,7 @@
CachedResult.Completion = Results[I].CreateCodeCompletionString(*TheSema,
*CachedCompletionAllocator);
CachedResult.ShowInContexts = getDeclShowContexts(Results[I].Declaration,
- Ctx->getLangOptions(),
+ Ctx->getLangOpts(),
IsNestedNameSpecifier);
CachedResult.Priority = Results[I].Priority;
CachedResult.Kind = Results[I].CursorKind;
@@ -397,7 +397,7 @@
CachedCompletionResults.push_back(CachedResult);
/// Handle nested-name-specifiers in C++.
- if (TheSema->Context.getLangOptions().CPlusPlus &&
+ if (TheSema->Context.getLangOpts().CPlusPlus &&
IsNestedNameSpecifier && !Results[I].StartsNestedNameSpecifier) {
// The contexts in which a nested-name-specifier can appear in C++.
unsigned NNSContexts
@@ -2033,7 +2033,7 @@
| (1LL << (CodeCompletionContext::CCC_ParenthesizedExpression - 1))
| (1LL << (CodeCompletionContext::CCC_Recovery - 1));
- if (AST.getASTContext().getLangOptions().CPlusPlus)
+ if (AST.getASTContext().getLangOpts().CPlusPlus)
NormalContexts |= (1LL << (CodeCompletionContext::CCC_EnumTag - 1))
| (1LL << (CodeCompletionContext::CCC_UnionTag - 1))
| (1LL << (CodeCompletionContext::CCC_ClassOrStructTag - 1));
@@ -2124,7 +2124,7 @@
unsigned HiddenIDNS = (Decl::IDNS_Type | Decl::IDNS_Member |
Decl::IDNS_Namespace | Decl::IDNS_Ordinary |
Decl::IDNS_NonMemberOperator);
- if (Ctx.getLangOptions().CPlusPlus)
+ if (Ctx.getLangOpts().CPlusPlus)
HiddenIDNS |= Decl::IDNS_Tag;
Hiding = (IDNS & HiddenIDNS);
}
@@ -2184,7 +2184,7 @@
if (!Context.getPreferredType().isNull()) {
if (C->Kind == CXCursor_MacroDefinition) {
Priority = getMacroUsagePriority(C->Completion->getTypedText(),
- S.getLangOptions(),
+ S.getLangOpts(),
Context.getPreferredType()->isAnyPointerType());
} else if (C->Type) {
CanQualType Expected
@@ -2411,8 +2411,10 @@
serialize(Out);
Out.close();
- if (Out.has_error())
+ if (Out.has_error()) {
+ Out.clear_error();
return CXSaveError_Unknown;
+ }
if (llvm::sys::fs::rename(TempPath.str(), File)) {
bool exists;
Modified: cfe/branches/tooling/lib/Frontend/CacheTokens.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/CacheTokens.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/CacheTokens.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/CacheTokens.cpp Mon Mar 19 14:02:20 2012
@@ -467,7 +467,7 @@
// Iterate over all the files in SourceManager. Create a lexer
// for each file and cache the tokens.
SourceManager &SM = PP.getSourceManager();
- const LangOptions &LOpts = PP.getLangOptions();
+ const LangOptions &LOpts = PP.getLangOpts();
for (SourceManager::fileinfo_iterator I = SM.fileinfo_begin(),
E = SM.fileinfo_end(); I != E; ++I) {
Modified: cfe/branches/tooling/lib/Frontend/ChainedIncludesSource.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/ChainedIncludesSource.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/ChainedIncludesSource.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/ChainedIncludesSource.cpp Mon Mar 19 14:02:20 2012
@@ -116,7 +116,7 @@
if (firstInclude) {
Preprocessor &PP = Clang->getPreprocessor();
PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
- PP.getLangOptions());
+ PP.getLangOpts());
} else {
assert(!serialBufs.empty());
SmallVector<llvm::MemoryBuffer *, 4> bufs;
Modified: cfe/branches/tooling/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/CompilerInvocation.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/CompilerInvocation.cpp Mon Mar 19 14:02:20 2012
@@ -78,13 +78,34 @@
static const char *getAnalysisPurgeModeName(AnalysisPurgeMode Kind) {
switch (Kind) {
default:
- llvm_unreachable("Unknown analysis client!");
+ llvm_unreachable("Unknown analysis purge mode!");
#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) \
case NAME: return CMDFLAG;
#include "clang/Frontend/Analyses.def"
}
}
+static const char *getAnalysisIPAModeName(AnalysisIPAMode Kind) {
+ switch (Kind) {
+ default:
+ llvm_unreachable("Unknown analysis ipa mode!");
+#define ANALYSIS_IPA(NAME, CMDFLAG, DESC) \
+ case NAME: return CMDFLAG;
+#include "clang/Frontend/Analyses.def"
+ }
+}
+
+static const char *
+ getAnalysisInliningModeName(AnalysisInliningMode Kind) {
+ switch (Kind) {
+ default:
+ llvm_unreachable("Unknown analysis inlining mode!");
+#define ANALYSIS_INLINE_SELECTION(NAME, CMDFLAG, DESC) \
+ case NAME: return CMDFLAG;
+#include "clang/Frontend/Analyses.def"
+ }
+}
+
//===----------------------------------------------------------------------===//
// Serialization (to args)
//===----------------------------------------------------------------------===//
@@ -113,6 +134,15 @@
Res.push_back("-analyze-function");
Res.push_back(Opts.AnalyzeSpecificFunction);
}
+ if (Opts.IPAMode != Inlining) {
+ Res.push_back("-analyzer-ipa");
+ Res.push_back(getAnalysisIPAModeName(Opts.IPAMode));
+ }
+ if (Opts.InliningMode != NoRedundancy) {
+ Res.push_back("-analyzer-inlining-mode");
+ Res.push_back(getAnalysisInliningModeName(Opts.InliningMode));
+ }
+
if (Opts.AnalyzeAll)
Res.push_back("-analyzer-opt-analyze-headers");
if (Opts.AnalyzerDisplayProgress)
@@ -1036,6 +1066,38 @@
}
}
+ if (Arg *A = Args.getLastArg(OPT_analyzer_ipa)) {
+ StringRef Name = A->getValue(Args);
+ AnalysisIPAMode Value = llvm::StringSwitch<AnalysisIPAMode>(Name)
+#define ANALYSIS_IPA(NAME, CMDFLAG, DESC) \
+ .Case(CMDFLAG, NAME)
+#include "clang/Frontend/Analyses.def"
+ .Default(NumIPAModes);
+ if (Value == NumIPAModes) {
+ Diags.Report(diag::err_drv_invalid_value)
+ << A->getAsString(Args) << Name;
+ Success = false;
+ } else {
+ Opts.IPAMode = Value;
+ }
+ }
+
+ if (Arg *A = Args.getLastArg(OPT_analyzer_inlining_mode)) {
+ StringRef Name = A->getValue(Args);
+ AnalysisInliningMode Value = llvm::StringSwitch<AnalysisInliningMode>(Name)
+#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) \
+ .Case(CMDFLAG, NAME)
+#include "clang/Frontend/Analyses.def"
+ .Default(NumInliningModes);
+ if (Value == NumInliningModes) {
+ Diags.Report(diag::err_drv_invalid_value)
+ << A->getAsString(Args) << Name;
+ Success = false;
+ } else {
+ Opts.InliningMode = Value;
+ }
+ }
+
Opts.ShowCheckerHelp = Args.hasArg(OPT_analyzer_checker_help);
Opts.VisualizeEGDot = Args.hasArg(OPT_analyzer_viz_egraph_graphviz);
Opts.VisualizeEGUbi = Args.hasArg(OPT_analyzer_viz_egraph_ubigraph);
@@ -1052,8 +1114,6 @@
Opts.MaxNodes = Args.getLastArgIntValue(OPT_analyzer_max_nodes, 150000,Diags);
Opts.MaxLoop = Args.getLastArgIntValue(OPT_analyzer_max_loop, 4, Diags);
Opts.EagerlyTrimEGraph = !Args.hasArg(OPT_analyzer_no_eagerly_trim_egraph);
- if (Args.hasArg(OPT_analyzer_inline_call))
- Opts.InlineCall = 1;
Opts.PrintStats = Args.hasArg(OPT_analyzer_stats);
Opts.InlineMaxStackDepth =
Args.getLastArgIntValue(OPT_analyzer_inline_max_stack_depth,
@@ -1105,6 +1165,7 @@
Opts.Inlining = (Opts.OptimizationLevel > 1) ? CodeGenOptions::NormalInlining
: CodeGenOptions::OnlyAlwaysInlining;
// -fno-inline-functions overrides OptimizationLevel > 1.
+ Opts.NoInline = Args.hasArg(OPT_fno_inline);
Opts.Inlining = Args.hasArg(OPT_fno_inline_functions) ?
CodeGenOptions::OnlyAlwaysInlining : Opts.Inlining;
@@ -1217,8 +1278,8 @@
Opts.DOTOutputFile = Args.getLastArgValue(OPT_dependency_dot);
}
-static bool ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
- DiagnosticsEngine &Diags) {
+bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
+ DiagnosticsEngine *Diags) {
using namespace cc1options;
bool Success = true;
@@ -1252,10 +1313,11 @@
else if (ShowOverloads == "all")
Opts.ShowOverloads = DiagnosticsEngine::Ovl_All;
else {
- Diags.Report(diag::err_drv_invalid_value)
+ Success = false;
+ if (Diags)
+ Diags->Report(diag::err_drv_invalid_value)
<< Args.getLastArg(OPT_fshow_overloads_EQ)->getAsString(Args)
<< ShowOverloads;
- Success = false;
}
StringRef ShowCategory =
@@ -1267,10 +1329,11 @@
else if (ShowCategory == "name")
Opts.ShowCategories = 2;
else {
- Diags.Report(diag::err_drv_invalid_value)
+ Success = false;
+ if (Diags)
+ Diags->Report(diag::err_drv_invalid_value)
<< Args.getLastArg(OPT_fdiagnostics_show_category)->getAsString(Args)
<< ShowCategory;
- Success = false;
}
StringRef Format =
@@ -1282,10 +1345,11 @@
else if (Format == "vi")
Opts.Format = DiagnosticOptions::Vi;
else {
- Diags.Report(diag::err_drv_invalid_value)
+ Success = false;
+ if (Diags)
+ Diags->Report(diag::err_drv_invalid_value)
<< Args.getLastArg(OPT_fdiagnostics_format)->getAsString(Args)
<< Format;
- Success = false;
}
Opts.ShowSourceRanges = Args.hasArg(OPT_fdiagnostics_print_source_range_info);
@@ -1306,13 +1370,23 @@
Opts.TabStop = Args.getLastArgIntValue(OPT_ftabstop,
DiagnosticOptions::DefaultTabStop, Diags);
if (Opts.TabStop == 0 || Opts.TabStop > DiagnosticOptions::MaxTabStop) {
- Diags.Report(diag::warn_ignoring_ftabstop_value)
- << Opts.TabStop << DiagnosticOptions::DefaultTabStop;
Opts.TabStop = DiagnosticOptions::DefaultTabStop;
+ if (Diags)
+ Diags->Report(diag::warn_ignoring_ftabstop_value)
+ << Opts.TabStop << DiagnosticOptions::DefaultTabStop;
}
Opts.MessageLength = Args.getLastArgIntValue(OPT_fmessage_length, 0, Diags);
Opts.DumpBuildInformation = Args.getLastArgValue(OPT_dump_build_information);
- Opts.Warnings = Args.getAllArgValues(OPT_W);
+
+ for (arg_iterator it = Args.filtered_begin(OPT_W),
+ ie = Args.filtered_end(); it != ie; ++it) {
+ StringRef V = (*it)->getValue(Args);
+ // "-Wl," and such are not warnings options.
+ if (V.startswith("l,") || V.startswith("a,") || V.startswith("p,"))
+ continue;
+
+ Opts.Warnings.push_back(V);
+ }
return Success;
}
@@ -1938,9 +2012,7 @@
// This is the __NO_INLINE__ define, which just depends on things like the
// optimization level and -fno-inline, not actually whether the backend has
// inlining enabled.
- //
- // FIXME: This is affected by other options (-fno-inline).
- Opts.NoInline = !Opt;
+ Opts.NoInlineDefine = !Opt || Args.hasArg(OPT_fno_inline);
Opts.FastMath = Args.hasArg(OPT_ffast_math);
@@ -2114,7 +2186,7 @@
Success = ParseAnalyzerArgs(Res.getAnalyzerOpts(), *Args, Diags) && Success;
Success = ParseMigratorArgs(Res.getMigratorOpts(), *Args) && Success;
ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), *Args);
- Success = ParseDiagnosticArgs(Res.getDiagnosticOpts(), *Args, Diags)
+ Success = ParseDiagnosticArgs(Res.getDiagnosticOpts(), *Args, &Diags)
&& Success;
ParseFileSystemArgs(Res.getFileSystemOpts(), *Args);
// FIXME: We shouldn't have to pass the DashX option around here
Modified: cfe/branches/tooling/lib/Frontend/FrontendAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/FrontendAction.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/FrontendAction.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/FrontendAction.cpp Mon Mar 19 14:02:20 2012
@@ -284,7 +284,7 @@
if (!CI.hasASTContext() || !CI.getASTContext().getExternalSource()) {
Preprocessor &PP = CI.getPreprocessor();
PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
- PP.getLangOptions());
+ PP.getLangOpts());
}
// If there is a layout overrides file, attach an external AST source that
Modified: cfe/branches/tooling/lib/Frontend/FrontendActions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/FrontendActions.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/FrontendActions.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/FrontendActions.cpp Mon Mar 19 14:02:20 2012
@@ -364,7 +364,7 @@
// Start lexing the specified input file.
const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
- Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOptions());
+ Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOpts());
RawLex.SetKeepWhitespaceMode(true);
Token RawTok;
Modified: cfe/branches/tooling/lib/Frontend/InitHeaderSearch.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/InitHeaderSearch.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/InitHeaderSearch.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/InitHeaderSearch.cpp Mon Mar 19 14:02:20 2012
@@ -387,6 +387,9 @@
AddMinGW64CXXPaths(HSOpts.ResourceDir, "4.7.0");
// mingw.org C++ include paths
AddMinGWCPlusPlusIncludePaths("/mingw/lib/gcc", "mingw32", "4.5.2"); //MSYS
+ AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.6.2");
+ AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.6.1");
+ AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.5.2");
AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.5.0");
AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.4.0");
AddMinGWCPlusPlusIncludePaths("c:/MinGW/lib/gcc", "mingw32", "4.3.0");
Modified: cfe/branches/tooling/lib/Frontend/InitPreprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/InitPreprocessor.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/InitPreprocessor.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/InitPreprocessor.cpp Mon Mar 19 14:02:20 2012
@@ -319,11 +319,14 @@
+ getClangFullRepositoryVersion() + ")\"");
#undef TOSTR
#undef TOSTR2
- // Currently claim to be compatible with GCC 4.2.1-5621.
- Builder.defineMacro("__GNUC_MINOR__", "2");
- Builder.defineMacro("__GNUC_PATCHLEVEL__", "1");
- Builder.defineMacro("__GNUC__", "4");
- Builder.defineMacro("__GXX_ABI_VERSION", "1002");
+ if (!LangOpts.MicrosoftMode) {
+ // Currently claim to be compatible with GCC 4.2.1-5621, but only if we're
+ // not compiling for MSVC compatibility
+ Builder.defineMacro("__GNUC_MINOR__", "2");
+ Builder.defineMacro("__GNUC_PATCHLEVEL__", "1");
+ Builder.defineMacro("__GNUC__", "4");
+ Builder.defineMacro("__GXX_ABI_VERSION", "1002");
+ }
// Define macros for the C11 / C++11 memory orderings
Builder.defineMacro("__ATOMIC_RELAXED", "0");
@@ -518,7 +521,7 @@
else
Builder.defineMacro("__GNUC_STDC_INLINE__");
- if (LangOpts.NoInline)
+ if (LangOpts.NoInlineDefine)
Builder.defineMacro("__NO_INLINE__");
if (unsigned PICLevel = LangOpts.PICLevel) {
@@ -629,7 +632,7 @@
const PreprocessorOptions &InitOpts,
const HeaderSearchOptions &HSOpts,
const FrontendOptions &FEOpts) {
- const LangOptions &LangOpts = PP.getLangOptions();
+ const LangOptions &LangOpts = PP.getLangOpts();
std::string PredefineBuffer;
PredefineBuffer.reserve(4080);
llvm::raw_string_ostream Predefines(PredefineBuffer);
@@ -641,7 +644,7 @@
// Emit line markers for various builtin sections of the file. We don't do
// this in asm preprocessor mode, because "# 4" is not a line marker directive
// in this mode.
- if (!PP.getLangOptions().AsmPreprocessor)
+ if (!PP.getLangOpts().AsmPreprocessor)
Builder.append("# 1 \"<built-in>\" 3");
// Install things like __POWERPC__, __GNUC__, etc into the macro table.
@@ -666,12 +669,12 @@
// Even with predefines off, some macros are still predefined.
// These should all be defined in the preprocessor according to the
// current language configuration.
- InitializeStandardPredefinedMacros(PP.getTargetInfo(), PP.getLangOptions(),
+ InitializeStandardPredefinedMacros(PP.getTargetInfo(), PP.getLangOpts(),
FEOpts, Builder);
// Add on the predefines from the driver. Wrap in a #line directive to report
// that they come from the command line.
- if (!PP.getLangOptions().AsmPreprocessor)
+ if (!PP.getLangOpts().AsmPreprocessor)
Builder.append("# 1 \"<command line>\" 1");
// Process #define's and #undef's in the order they are given.
@@ -699,7 +702,7 @@
}
// Exit the command line and go back to <built-in> (2 is LC_LEAVE).
- if (!PP.getLangOptions().AsmPreprocessor)
+ if (!PP.getLangOpts().AsmPreprocessor)
Builder.append("# 1 \"<built-in>\" 2");
// Instruct the preprocessor to skip the preamble.
@@ -711,6 +714,6 @@
// Initialize the header search object.
ApplyHeaderSearchOptions(PP.getHeaderSearchInfo(), HSOpts,
- PP.getLangOptions(),
+ PP.getLangOpts(),
PP.getTargetInfo().getTriple());
}
Modified: cfe/branches/tooling/lib/Frontend/PrintPreprocessedOutput.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/PrintPreprocessedOutput.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/PrintPreprocessedOutput.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/PrintPreprocessedOutput.cpp Mon Mar 19 14:02:20 2012
@@ -108,7 +108,7 @@
Initialized = false;
// If we're in microsoft mode, use normal #line instead of line markers.
- UseLineDirective = PP.getLangOptions().MicrosoftExt;
+ UseLineDirective = PP.getLangOpts().MicrosoftExt;
}
void SetEmittedTokensOnThisLine() { EmittedTokensOnThisLine = true; }
Modified: cfe/branches/tooling/lib/Frontend/VerifyDiagnosticConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/VerifyDiagnosticConsumer.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/VerifyDiagnosticConsumer.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/VerifyDiagnosticConsumer.cpp Mon Mar 19 14:02:20 2012
@@ -348,7 +348,7 @@
SourceManager& SM = PP.getSourceManager();
// Create a lexer to lex all the tokens of the main file in raw mode.
const llvm::MemoryBuffer *FromFile = SM.getBuffer(FID);
- Lexer RawLex(FID, FromFile, SM, PP.getLangOptions());
+ Lexer RawLex(FID, FromFile, SM, PP.getLangOpts());
// Return comments as tokens, this is how we find expected diagnostics.
RawLex.SetCommentRetentionState(true);
Modified: cfe/branches/tooling/lib/Index/ASTLocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Index/ASTLocation.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Index/ASTLocation.cpp (original)
+++ cfe/branches/tooling/lib/Index/ASTLocation.cpp Mon Mar 19 14:02:20 2012
@@ -89,7 +89,7 @@
case N_Stmt:
OS << "[Stmt: " << AsStmt()->getStmtClassName() << " ";
- AsStmt()->printPretty(OS, Ctx, 0, PrintingPolicy(Ctx.getLangOptions()));
+ AsStmt()->printPretty(OS, Ctx, 0, PrintingPolicy(Ctx.getLangOpts()));
break;
case N_NamedRef:
Modified: cfe/branches/tooling/lib/Lex/Lexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Lex/Lexer.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Lex/Lexer.cpp (original)
+++ cfe/branches/tooling/lib/Lex/Lexer.cpp Mon Mar 19 14:02:20 2012
@@ -117,7 +117,7 @@
Lexer::Lexer(FileID FID, const llvm::MemoryBuffer *InputFile, Preprocessor &PP)
: PreprocessorLexer(&PP, FID),
FileLoc(PP.getSourceManager().getLocForStartOfFile(FID)),
- Features(PP.getLangOptions()) {
+ LangOpts(PP.getLangOpts()) {
InitLexer(InputFile->getBufferStart(), InputFile->getBufferStart(),
InputFile->getBufferEnd());
@@ -129,9 +129,9 @@
/// Lexer constructor - Create a new raw lexer object. This object is only
/// suitable for calls to 'LexRawToken'. This lexer assumes that the text
/// range will outlive it, so it doesn't take ownership of it.
-Lexer::Lexer(SourceLocation fileloc, const LangOptions &features,
+Lexer::Lexer(SourceLocation fileloc, const LangOptions &langOpts,
const char *BufStart, const char *BufPtr, const char *BufEnd)
- : FileLoc(fileloc), Features(features) {
+ : FileLoc(fileloc), LangOpts(langOpts) {
InitLexer(BufStart, BufPtr, BufEnd);
@@ -143,8 +143,8 @@
/// suitable for calls to 'LexRawToken'. This lexer assumes that the text
/// range will outlive it, so it doesn't take ownership of it.
Lexer::Lexer(FileID FID, const llvm::MemoryBuffer *FromFile,
- const SourceManager &SM, const LangOptions &features)
- : FileLoc(SM.getLocForStartOfFile(FID)), Features(features) {
+ const SourceManager &SM, const LangOptions &langOpts)
+ : FileLoc(SM.getLocForStartOfFile(FID)), LangOpts(langOpts) {
InitLexer(FromFile->getBufferStart(), FromFile->getBufferStart(),
FromFile->getBufferEnd());
@@ -287,7 +287,7 @@
/// wants to get the true, uncanonicalized, spelling of things like digraphs
/// UCNs, etc.
std::string Lexer::getSpelling(const Token &Tok, const SourceManager &SourceMgr,
- const LangOptions &Features, bool *Invalid) {
+ const LangOptions &LangOpts, bool *Invalid) {
assert((int)Tok.getLength() >= 0 && "Token character range is bogus!");
// If this token contains nothing interesting, return it directly.
@@ -309,7 +309,7 @@
for (const char *Ptr = TokStart, *End = TokStart+Tok.getLength();
Ptr != End; ) {
unsigned CharSize;
- Result.push_back(Lexer::getCharAndSizeNoWarn(Ptr, CharSize, Features));
+ Result.push_back(Lexer::getCharAndSizeNoWarn(Ptr, CharSize, LangOpts));
Ptr += CharSize;
}
assert(Result.size() != unsigned(Tok.getLength()) &&
@@ -329,7 +329,7 @@
/// if an internal buffer is returned.
unsigned Lexer::getSpelling(const Token &Tok, const char *&Buffer,
const SourceManager &SourceMgr,
- const LangOptions &Features, bool *Invalid) {
+ const LangOptions &LangOpts, bool *Invalid) {
assert((int)Tok.getLength() >= 0 && "Token character range is bogus!");
const char *TokStart = 0;
@@ -369,7 +369,7 @@
for (const char *Ptr = TokStart, *End = TokStart+Tok.getLength();
Ptr != End; ) {
unsigned CharSize;
- *OutBuf++ = Lexer::getCharAndSizeNoWarn(Ptr, CharSize, Features);
+ *OutBuf++ = Lexer::getCharAndSizeNoWarn(Ptr, CharSize, LangOpts);
Ptr += CharSize;
}
assert(unsigned(OutBuf-Buffer) != Tok.getLength() &&
@@ -508,13 +508,13 @@
std::pair<unsigned, bool>
Lexer::ComputePreamble(const llvm::MemoryBuffer *Buffer,
- const LangOptions &Features, unsigned MaxLines) {
+ const LangOptions &LangOpts, unsigned MaxLines) {
// Create a lexer starting at the beginning of the file. Note that we use a
// "fake" file source location at offset 1 so that the lexer will track our
// position within the file.
const unsigned StartOffset = 1;
SourceLocation StartLoc = SourceLocation::getFromRawEncoding(StartOffset);
- Lexer TheLexer(StartLoc, Features, Buffer->getBufferStart(),
+ Lexer TheLexer(StartLoc, LangOpts, Buffer->getBufferStart(),
Buffer->getBufferStart(), Buffer->getBufferEnd());
bool InPreprocessorDirective = false;
@@ -658,7 +658,7 @@
SourceLocation Lexer::AdvanceToTokenCharacter(SourceLocation TokStart,
unsigned CharNo,
const SourceManager &SM,
- const LangOptions &Features) {
+ const LangOptions &LangOpts) {
// Figure out how many physical characters away the specified expansion
// character is. This needs to take into consideration newlines and
// trigraphs.
@@ -684,7 +684,7 @@
// lexer to parse it correctly.
for (; CharNo; --CharNo) {
unsigned Size;
- Lexer::getCharAndSizeNoWarn(TokPtr, Size, Features);
+ Lexer::getCharAndSizeNoWarn(TokPtr, Size, LangOpts);
TokPtr += Size;
PhysOffset += Size;
}
@@ -716,16 +716,16 @@
/// a source location pointing to the last character in the token, etc.
SourceLocation Lexer::getLocForEndOfToken(SourceLocation Loc, unsigned Offset,
const SourceManager &SM,
- const LangOptions &Features) {
+ const LangOptions &LangOpts) {
if (Loc.isInvalid())
return SourceLocation();
if (Loc.isMacroID()) {
- if (Offset > 0 || !isAtEndOfMacroExpansion(Loc, SM, Features, &Loc))
+ if (Offset > 0 || !isAtEndOfMacroExpansion(Loc, SM, LangOpts, &Loc))
return SourceLocation(); // Points inside the macro expansion.
}
- unsigned Len = Lexer::MeasureTokenLength(Loc, SM, Features);
+ unsigned Len = Lexer::MeasureTokenLength(Loc, SM, LangOpts);
if (Len > Offset)
Len = Len - Offset;
else
@@ -1212,7 +1212,7 @@
char Res = GetTrigraphCharForLetter(*CP);
if (!Res || !L) return Res;
- if (!L->getFeatures().Trigraphs) {
+ if (!L->getLangOpts().Trigraphs) {
if (!L->isLexingRawMode())
L->Diag(CP-2, diag::trigraph_ignored);
return 0;
@@ -1405,7 +1405,7 @@
/// NOTE: When this method is updated, getCharAndSizeSlow (above) should
/// be updated to match.
char Lexer::getCharAndSizeSlowNoWarn(const char *Ptr, unsigned &Size,
- const LangOptions &Features) {
+ const LangOptions &LangOpts) {
// If we have a slash, look for an escaped newline.
if (Ptr[0] == '\\') {
++Size;
@@ -1427,7 +1427,7 @@
return ' ';
// Use slow version to accumulate a correct size field.
- return getCharAndSizeSlowNoWarn(Ptr, Size, Features);
+ return getCharAndSizeSlowNoWarn(Ptr, Size, LangOpts);
}
// Otherwise, this is not an escaped newline, just return the slash.
@@ -1435,7 +1435,7 @@
}
// If this is a trigraph, process it.
- if (Features.Trigraphs && Ptr[0] == '?' && Ptr[1] == '?') {
+ if (LangOpts.Trigraphs && Ptr[0] == '?' && Ptr[1] == '?') {
// If this is actually a legal trigraph (not something like "??x"), return
// it.
if (char C = GetTrigraphCharForLetter(Ptr[2])) {
@@ -1478,7 +1478,7 @@
//
// TODO: Could merge these checks into a CharInfo flag to make the comparison
// cheaper
- if (C != '\\' && C != '?' && (C != '$' || !Features.DollarIdents)) {
+ if (C != '\\' && C != '?' && (C != '$' || !LangOpts.DollarIdents)) {
FinishIdentifier:
const char *IdStart = BufferPtr;
FormTokenWithChars(Result, CurPtr, tok::raw_identifier);
@@ -1507,7 +1507,7 @@
while (1) {
if (C == '$') {
// If we hit a $ and they are not supported in identifiers, we are done.
- if (!Features.DollarIdents) goto FinishIdentifier;
+ if (!LangOpts.DollarIdents) goto FinishIdentifier;
// Otherwise, emit a diagnostic and continue.
if (!isLexingRawMode())
@@ -1533,12 +1533,12 @@
/// isHexaLiteral - Return true if Start points to a hex constant.
/// in microsoft mode (where this is supposed to be several different tokens).
-static bool isHexaLiteral(const char *Start, const LangOptions &Features) {
+static bool isHexaLiteral(const char *Start, const LangOptions &LangOpts) {
unsigned Size;
- char C1 = Lexer::getCharAndSizeNoWarn(Start, Size, Features);
+ char C1 = Lexer::getCharAndSizeNoWarn(Start, Size, LangOpts);
if (C1 != '0')
return false;
- char C2 = Lexer::getCharAndSizeNoWarn(Start + Size, Size, Features);
+ char C2 = Lexer::getCharAndSizeNoWarn(Start + Size, Size, LangOpts);
return (C2 == 'x' || C2 == 'X');
}
@@ -1559,7 +1559,7 @@
if ((C == '-' || C == '+') && (PrevCh == 'E' || PrevCh == 'e')) {
// If we are in Microsoft mode, don't continue if the constant is hex.
// For example, MSVC will accept the following as 3 tokens: 0x1234567e+1
- if (!Features.MicrosoftExt || !isHexaLiteral(BufferPtr, Features))
+ if (!LangOpts.MicrosoftExt || !isHexaLiteral(BufferPtr, LangOpts))
return LexNumericConstant(Result, ConsumeChar(CurPtr, Size, Result));
}
@@ -1576,13 +1576,13 @@
/// LexUDSuffix - Lex the ud-suffix production for user-defined literal suffixes
/// in C++11, or warn on a ud-suffix in C++98.
const char *Lexer::LexUDSuffix(Token &Result, const char *CurPtr) {
- assert(getFeatures().CPlusPlus);
+ assert(getLangOpts().CPlusPlus);
// Maximally munch an identifier. FIXME: UCNs.
unsigned Size;
char C = getCharAndSize(CurPtr, Size);
if (isIdentifierHead(C)) {
- if (!getFeatures().CPlusPlus0x) {
+ if (!getLangOpts().CPlusPlus0x) {
if (!isLexingRawMode())
Diag(CurPtr,
C == '_' ? diag::warn_cxx11_compat_user_defined_literal
@@ -1632,7 +1632,7 @@
if (C == '\n' || C == '\r' || // Newline.
(C == 0 && CurPtr-1 == BufferEnd)) { // End of file.
- if (!isLexingRawMode() && !Features.AsmPreprocessor)
+ if (!isLexingRawMode() && !LangOpts.AsmPreprocessor)
Diag(BufferPtr, diag::warn_unterminated_string);
FormTokenWithChars(Result, CurPtr-1, tok::unknown);
return;
@@ -1651,7 +1651,7 @@
}
// If we are in C++11, lex the optional ud-suffix.
- if (getFeatures().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
CurPtr = LexUDSuffix(Result, CurPtr);
// If a nul character existed in the string, warn about it.
@@ -1734,7 +1734,7 @@
}
// If we are in C++11, lex the optional ud-suffix.
- if (getFeatures().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
CurPtr = LexUDSuffix(Result, CurPtr);
// Update the location of token as well as BufferPtr.
@@ -1790,7 +1790,7 @@
char C = getAndAdvanceChar(CurPtr, Result);
if (C == '\'') {
- if (!isLexingRawMode() && !Features.AsmPreprocessor)
+ if (!isLexingRawMode() && !LangOpts.AsmPreprocessor)
Diag(BufferPtr, diag::err_empty_character);
FormTokenWithChars(Result, CurPtr, tok::unknown);
return;
@@ -1804,7 +1804,7 @@
C = getAndAdvanceChar(CurPtr, Result);
} else if (C == '\n' || C == '\r' || // Newline.
(C == 0 && CurPtr-1 == BufferEnd)) { // End of file.
- if (!isLexingRawMode() && !Features.AsmPreprocessor)
+ if (!isLexingRawMode() && !LangOpts.AsmPreprocessor)
Diag(BufferPtr, diag::warn_unterminated_char);
FormTokenWithChars(Result, CurPtr-1, tok::unknown);
return;
@@ -1821,7 +1821,7 @@
}
// If we are in C++11, lex the optional ud-suffix.
- if (getFeatures().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
CurPtr = LexUDSuffix(Result, CurPtr);
// If a nul character existed in the character, warn about it.
@@ -1889,12 +1889,12 @@
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 && !isLexingRawMode()) {
+ if (!LangOpts.BCPLComment && !isLexingRawMode()) {
Diag(BufferPtr, diag::ext_bcpl_comment);
// Mark them enabled so we only emit one warning for this translation
// unit.
- Features.BCPLComment = true;
+ LangOpts.BCPLComment = true;
}
// Scan over the body of the comment. The common case, when scanning, is that
@@ -2081,7 +2081,7 @@
// If no trigraphs are enabled, warn that we ignored this trigraph and
// ignore this * character.
- if (!L->getFeatures().Trigraphs) {
+ if (!L->getLangOpts().Trigraphs) {
if (!L->isLexingRawMode())
L->Diag(CurPtr, diag::trigraph_ignored_block_comment);
return false;
@@ -2600,7 +2600,7 @@
case 26: // DOS & CP/M EOF: "^Z".
// If we're in Microsoft extensions mode, treat this as end of file.
- if (Features.MicrosoftExt) {
+ if (LangOpts.MicrosoftExt) {
// Read the PP instance variable into an automatic variable, because
// LexEndOfFile will often delete 'this'.
Preprocessor *PPCache = PP;
@@ -2653,7 +2653,7 @@
// 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] == '/' && !inKeepCommentMode() &&
- Features.BCPLComment && !Features.TraditionalCPP) {
+ LangOpts.BCPLComment && !LangOpts.TraditionalCPP) {
if (SkipBCPLComment(Result, CurPtr+2))
return; // There is a token to return.
goto SkipIgnoredUnits;
@@ -2678,7 +2678,7 @@
// Notify MIOpt that we read a non-whitespace/non-comment token.
MIOpt.ReadToken();
- if (Features.CPlusPlus0x) {
+ if (LangOpts.CPlusPlus0x) {
Char = getCharAndSize(CurPtr, SizeTmp);
// UTF-16 string literal
@@ -2730,7 +2730,7 @@
// Notify MIOpt that we read a non-whitespace/non-comment token.
MIOpt.ReadToken();
- if (Features.CPlusPlus0x) {
+ if (LangOpts.CPlusPlus0x) {
Char = getCharAndSize(CurPtr, SizeTmp);
// UTF-32 string literal
@@ -2758,7 +2758,7 @@
// Notify MIOpt that we read a non-whitespace/non-comment token.
MIOpt.ReadToken();
- if (Features.CPlusPlus0x) {
+ if (LangOpts.CPlusPlus0x) {
Char = getCharAndSize(CurPtr, SizeTmp);
if (Char == '"')
@@ -2781,7 +2781,7 @@
tok::wide_string_literal);
// Wide raw string literal.
- if (Features.CPlusPlus0x && Char == 'R' &&
+ if (LangOpts.CPlusPlus0x && Char == 'R' &&
getCharAndSize(CurPtr + SizeTmp, SizeTmp2) == '"')
return LexRawStringLiteral(Result,
ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result),
@@ -2809,7 +2809,7 @@
return LexIdentifier(Result, CurPtr);
case '$': // $ in identifiers.
- if (Features.DollarIdents) {
+ if (LangOpts.DollarIdents) {
if (!isLexingRawMode())
Diag(CurPtr-1, diag::ext_dollar_in_identifier);
// Notify MIOpt that we read a non-whitespace/non-comment token.
@@ -2861,7 +2861,7 @@
MIOpt.ReadToken();
return LexNumericConstant(Result, ConsumeChar(CurPtr, SizeTmp, Result));
- } else if (Features.CPlusPlus && Char == '*') {
+ } else if (LangOpts.CPlusPlus && Char == '*') {
Kind = tok::periodstar;
CurPtr += SizeTmp;
} else if (Char == '.' &&
@@ -2910,7 +2910,7 @@
if (Char == '-') { // --
CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
Kind = tok::minusminus;
- } else if (Char == '>' && Features.CPlusPlus &&
+ } else if (Char == '>' && LangOpts.CPlusPlus &&
getCharAndSize(CurPtr+SizeTmp, SizeTmp2) == '*') { // C++ ->*
CurPtr = ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result),
SizeTmp2, Result);
@@ -2948,9 +2948,9 @@
// "foo". Check to see if the character after the second slash is a '*'.
// If so, we will lex that as a "/" instead of the start of a comment.
// However, we never do this in -traditional-cpp mode.
- if ((Features.BCPLComment ||
+ if ((LangOpts.BCPLComment ||
getCharAndSize(CurPtr+SizeTmp, SizeTmp2) != '*') &&
- !Features.TraditionalCPP) {
+ !LangOpts.TraditionalCPP) {
if (SkipBCPLComment(Result, ConsumeChar(CurPtr, SizeTmp, Result)))
return; // There is a token to return.
@@ -2979,17 +2979,17 @@
if (Char == '=') {
Kind = tok::percentequal;
CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else if (Features.Digraphs && Char == '>') {
+ } else if (LangOpts.Digraphs && Char == '>') {
Kind = tok::r_brace; // '%>' -> '}'
CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else if (Features.Digraphs && Char == ':') {
+ } else if (LangOpts.Digraphs && Char == ':') {
CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
Char = getCharAndSize(CurPtr, SizeTmp);
if (Char == '%' && getCharAndSize(CurPtr+SizeTmp, SizeTmp2) == ':') {
Kind = tok::hashhash; // '%:%:' -> '##'
CurPtr = ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result),
SizeTmp2, Result);
- } else if (Char == '@' && Features.MicrosoftExt) {// %:@ -> #@ -> Charize
+ } else if (Char == '@' && LangOpts.MicrosoftExt) {// %:@ -> #@ -> Charize
CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
if (!isLexingRawMode())
Diag(BufferPtr, diag::ext_charize_microsoft);
@@ -3044,7 +3044,7 @@
// If this is '<<<<' and we're in a Perforce-style conflict marker,
// ignore it.
goto LexNextToken;
- } else if (Features.CUDA && After == '<') {
+ } else if (LangOpts.CUDA && After == '<') {
Kind = tok::lesslessless;
CurPtr = ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result),
SizeTmp2, Result);
@@ -3055,8 +3055,8 @@
} else if (Char == '=') {
CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
Kind = tok::lessequal;
- } else if (Features.Digraphs && Char == ':') { // '<:' -> '['
- if (Features.CPlusPlus0x &&
+ } else if (LangOpts.Digraphs && Char == ':') { // '<:' -> '['
+ if (LangOpts.CPlusPlus0x &&
getCharAndSize(CurPtr + SizeTmp, SizeTmp2) == ':') {
// C++0x [lex.pptoken]p3:
// Otherwise, if the next three characters are <:: and the subsequent
@@ -3075,7 +3075,7 @@
CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
Kind = tok::l_square;
- } else if (Features.Digraphs && Char == '%') { // '<%' -> '{'
+ } else if (LangOpts.Digraphs && Char == '%') { // '<%' -> '{'
CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
Kind = tok::l_brace;
} else {
@@ -3100,7 +3100,7 @@
} else if (After == '>' && HandleEndOfConflictMarker(CurPtr-1)) {
// If this is '>>>>>>>' and we're in a conflict marker, ignore it.
goto LexNextToken;
- } else if (Features.CUDA && After == '>') {
+ } else if (LangOpts.CUDA && After == '>') {
Kind = tok::greatergreatergreater;
CurPtr = ConsumeChar(ConsumeChar(CurPtr, SizeTmp, Result),
SizeTmp2, Result);
@@ -3139,10 +3139,10 @@
break;
case ':':
Char = getCharAndSize(CurPtr, SizeTmp);
- if (Features.Digraphs && Char == '>') {
+ if (LangOpts.Digraphs && Char == '>') {
Kind = tok::r_square; // ':>' -> ']'
CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else if (Features.CPlusPlus && Char == ':') {
+ } else if (LangOpts.CPlusPlus && Char == ':') {
Kind = tok::coloncolon;
CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
} else {
@@ -3173,7 +3173,7 @@
if (Char == '#') {
Kind = tok::hashhash;
CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
- } else if (Char == '@' && Features.MicrosoftExt) { // #@ -> Charize
+ } else if (Char == '@' && LangOpts.MicrosoftExt) { // #@ -> Charize
Kind = tok::hashat;
if (!isLexingRawMode())
Diag(BufferPtr, diag::ext_charize_microsoft);
@@ -3209,7 +3209,7 @@
case '@':
// Objective C support.
- if (CurPtr[-1] == '@' && Features.ObjC1)
+ if (CurPtr[-1] == '@' && LangOpts.ObjC1)
Kind = tok::at;
else
Kind = tok::unknown;
Modified: cfe/branches/tooling/lib/Lex/LiteralSupport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Lex/LiteralSupport.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Lex/LiteralSupport.cpp (original)
+++ cfe/branches/tooling/lib/Lex/LiteralSupport.cpp Mon Mar 19 14:02:20 2012
@@ -179,7 +179,8 @@
/// ProcessUCNEscape - Read the Universal Character Name, check constraints and
/// return the UTF32.
-static bool ProcessUCNEscape(const char *&ThisTokBuf, const char *ThisTokEnd,
+static bool ProcessUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf,
+ const char *ThisTokEnd,
uint32_t &UcnVal, unsigned short &UcnLen,
FullSourceLoc Loc, DiagnosticsEngine *Diags,
const LangOptions &Features,
@@ -187,8 +188,7 @@
if (!Features.CPlusPlus && !Features.C99 && Diags)
Diags->Report(Loc, diag::warn_ucn_not_valid_in_c89);
- // Save the beginning of the string (for error diagnostics).
- const char *ThisTokBegin = ThisTokBuf;
+ const char *UcnBegin = ThisTokBuf;
// Skip the '\u' char's.
ThisTokBuf += 2;
@@ -210,31 +210,43 @@
if (UcnLenSave) {
if (Diags) {
SourceLocation L =
- Lexer::AdvanceToTokenCharacter(Loc, ThisTokBuf-ThisTokBegin,
+ Lexer::AdvanceToTokenCharacter(Loc, UcnBegin - ThisTokBegin,
Loc.getManager(), Features);
- Diags->Report(FullSourceLoc(L, Loc.getManager()),
- diag::err_ucn_escape_incomplete);
+ Diags->Report(L, diag::err_ucn_escape_incomplete);
}
return false;
}
+
// Check UCN constraints (C99 6.4.3p2) [C++11 lex.charset p2]
- bool invalid_ucn = (0xD800<=UcnVal && UcnVal<=0xDFFF) // surrogate codepoints
- || 0x10FFFF < UcnVal; // maximum legal UTF32 value
+ if ((0xD800 <= UcnVal && UcnVal <= 0xDFFF) || // surrogate codepoints
+ UcnVal > 0x10FFFF) { // maximum legal UTF32 value
+ if (Diags)
+ Diags->Report(Loc, diag::err_ucn_escape_invalid);
+ return false;
+ }
// C++11 allows UCNs that refer to control characters and basic source
// characters inside character and string literals
- if (!Features.CPlusPlus0x || !in_char_string_literal) {
- if ((UcnVal < 0xa0 &&
- (UcnVal != 0x24 && UcnVal != 0x40 && UcnVal != 0x60 ))) { // $, @, `
- invalid_ucn = true;
+ if (UcnVal < 0xa0 &&
+ (UcnVal != 0x24 && UcnVal != 0x40 && UcnVal != 0x60)) { // $, @, `
+ bool IsError = (!Features.CPlusPlus0x || !in_char_string_literal);
+ if (Diags) {
+ SourceLocation UcnBeginLoc =
+ Lexer::AdvanceToTokenCharacter(Loc, UcnBegin - ThisTokBegin,
+ Loc.getManager(), Features);
+ char BasicSCSChar = UcnVal;
+ if (UcnVal >= 0x20 && UcnVal < 0x7f)
+ Diags->Report(UcnBeginLoc, IsError ? diag::err_ucn_escape_basic_scs :
+ diag::warn_cxx98_compat_literal_ucn_escape_basic_scs)
+ << StringRef(&BasicSCSChar, 1);
+ else
+ Diags->Report(UcnBeginLoc, IsError ? diag::err_ucn_control_character :
+ diag::warn_cxx98_compat_literal_ucn_control_character);
}
+ if (IsError)
+ return false;
}
- if (invalid_ucn) {
- if (Diags)
- Diags->Report(Loc, diag::err_ucn_escape_invalid);
- return false;
- }
return true;
}
@@ -242,7 +254,8 @@
/// convert the UTF32 to UTF8 or UTF16. This is a subroutine of
/// StringLiteralParser. When we decide to implement UCN's for identifiers,
/// we will likely rework our support for UCN's.
-static void EncodeUCNEscape(const char *&ThisTokBuf, const char *ThisTokEnd,
+static void EncodeUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf,
+ const char *ThisTokEnd,
char *&ResultBuf, bool &HadError,
FullSourceLoc Loc, unsigned CharByteWidth,
DiagnosticsEngine *Diags,
@@ -250,8 +263,8 @@
typedef uint32_t UTF32;
UTF32 UcnVal = 0;
unsigned short UcnLen = 0;
- if (!ProcessUCNEscape(ThisTokBuf, ThisTokEnd, UcnVal, UcnLen, Loc, Diags,
- Features)) {
+ if (!ProcessUCNEscape(ThisTokBegin, ThisTokBuf, ThisTokEnd, UcnVal, UcnLen,
+ Loc, Diags, Features, true)) {
HadError = 1;
return;
}
@@ -333,7 +346,7 @@
/// decimal-constant integer-suffix
/// octal-constant integer-suffix
/// hexadecimal-constant integer-suffix
-/// user-defiend-integer-literal: [C++11 lex.ext]
+/// user-defined-integer-literal: [C++11 lex.ext]
/// decimal-literal ud-suffix
/// octal-literal ud-suffix
/// hexadecimal-literal ud-suffix
@@ -469,7 +482,7 @@
continue; // Success.
case 'i':
case 'I':
- if (PP.getLangOptions().MicrosoftExt) {
+ if (PP.getLangOpts().MicrosoftExt) {
if (isFPConstant || isLong || isLongLong) break;
// Allow i8, i16, i32, i64, and i128.
@@ -529,7 +542,7 @@
}
if (s != ThisTokEnd) {
- if (PP.getLangOptions().CPlusPlus0x && s == SuffixBegin && *s == '_') {
+ if (PP.getLangOpts().CPlusPlus0x && s == SuffixBegin && *s == '_') {
// We have a ud-suffix! By C++11 [lex.ext]p10, ud-suffixes not starting
// with an '_' are ill-formed.
saw_ud_suffix = true;
@@ -595,7 +608,7 @@
}
s = first_non_digit;
- if (!PP.getLangOptions().HexFloats)
+ if (!PP.getLangOpts().HexFloats)
PP.Diag(TokLoc, diag::ext_hexconstant_invalid);
} else if (saw_period) {
PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin),
@@ -787,6 +800,8 @@
Kind = kind;
+ const char *TokBegin = begin;
+
// Skip over wide character determinant.
if (Kind != tok::char_constant) {
++begin;
@@ -803,7 +818,7 @@
--end;
} while (end[-1] != '\'');
UDSuffixBuf.assign(end, UDSuffixEnd);
- UDSuffixOffset = end - begin + 1;
+ UDSuffixOffset = end - TokBegin;
}
// Trim the ending quote.
@@ -885,9 +900,9 @@
// Is this a Universal Character Name excape?
if (begin[1] == 'u' || begin[1] == 'U') {
unsigned short UcnLen = 0;
- if (!ProcessUCNEscape(begin, end, *buffer_begin, UcnLen,
+ if (!ProcessUCNEscape(TokBegin, begin, end, *buffer_begin, UcnLen,
FullSourceLoc(Loc, PP.getSourceManager()),
- &PP.getDiagnostics(), PP.getLangOptions(),
+ &PP.getDiagnostics(), PP.getLangOpts(),
true))
{
HadError = true;
@@ -952,7 +967,7 @@
// character constants are not sign extended in the this implementation:
// '\xFF\xFF' = 65536 and '\x0\xFF' = 255, which matches GCC.
if (isAscii() && NumCharsSoFar == 1 && (Value & 128) &&
- PP.getLangOptions().CharIsSigned)
+ PP.getLangOpts().CharIsSigned)
Value = (signed char)Value;
}
@@ -1012,7 +1027,7 @@
StringLiteralParser::
StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
Preprocessor &PP, bool Complain)
- : SM(PP.getSourceManager()), Features(PP.getLangOptions()),
+ : SM(PP.getSourceManager()), Features(PP.getLangOpts()),
Target(PP.getTargetInfo()), Diags(Complain ? &PP.getDiagnostics() : 0),
MaxTokenLength(0), SizeBound(0), CharByteWidth(0), Kind(tok::unknown),
ResultPtr(ResultBuf.data()), hadError(false), Pascal(false) {
@@ -1113,6 +1128,7 @@
continue;
}
+ const char *ThisTokBegin = ThisTokBuf;
const char *ThisTokEnd = ThisTokBuf+ThisTokLen;
// Remove an optional ud-suffix.
@@ -1167,17 +1183,14 @@
++ThisTokBuf;
++ThisTokBuf; // skip '('
- // remove same number of characters from the end
- if (ThisTokEnd >= ThisTokBuf + (ThisTokBuf - Prefix))
- ThisTokEnd -= (ThisTokBuf - Prefix);
+ // Remove same number of characters from the end
+ ThisTokEnd -= ThisTokBuf - Prefix;
+ assert(ThisTokEnd >= ThisTokBuf && "malformed raw string literal");
// Copy the string over
- if (CopyStringFragment(StringRef(ThisTokBuf,ThisTokEnd-ThisTokBuf)))
- {
+ if (CopyStringFragment(StringRef(ThisTokBuf, ThisTokEnd - ThisTokBuf)))
if (DiagnoseBadString(StringToks[i]))
hadError = true;
- }
-
} else {
assert(ThisTokBuf[0] == '"' && "Expected quote, lexer broken?");
++ThisTokBuf; // skip "
@@ -1204,17 +1217,16 @@
} while (ThisTokBuf != ThisTokEnd && ThisTokBuf[0] != '\\');
// Copy the character span over.
- if (CopyStringFragment(StringRef(InStart,ThisTokBuf-InStart)))
- {
+ if (CopyStringFragment(StringRef(InStart, ThisTokBuf - InStart)))
if (DiagnoseBadString(StringToks[i]))
hadError = true;
- }
continue;
}
// Is this a Universal Character Name escape?
if (ThisTokBuf[1] == 'u' || ThisTokBuf[1] == 'U') {
- EncodeUCNEscape(ThisTokBuf, ThisTokEnd, ResultPtr,
- hadError, FullSourceLoc(StringToks[i].getLocation(),SM),
+ EncodeUCNEscape(ThisTokBegin, ThisTokBuf, ThisTokEnd,
+ ResultPtr, hadError,
+ FullSourceLoc(StringToks[i].getLocation(), SM),
CharByteWidth, Diags, Features);
continue;
}
@@ -1292,8 +1304,8 @@
ConversionResult result = conversionOK;
// Copy the character span over.
if (CharByteWidth == 1) {
- if (!isLegalUTF8Sequence(reinterpret_cast<const UTF8*>(Fragment.begin()),
- reinterpret_cast<const UTF8*>(Fragment.end())))
+ if (!isLegalUTF8String(reinterpret_cast<const UTF8*>(Fragment.begin()),
+ reinterpret_cast<const UTF8*>(Fragment.end())))
result = sourceIllegal;
memcpy(ResultPtr, Fragment.data(), Fragment.size());
ResultPtr += Fragment.size();
Modified: cfe/branches/tooling/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Lex/PPDirectives.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Lex/PPDirectives.cpp (original)
+++ cfe/branches/tooling/lib/Lex/PPDirectives.cpp Mon Mar 19 14:02:20 2012
@@ -124,7 +124,7 @@
const IdentifierInfo &Info = Identifiers.get(Spelling);
// Allow #defining |and| and friends in microsoft mode.
- if (Info.isCPlusPlusOperatorKeyword() && getLangOptions().MicrosoftMode) {
+ if (Info.isCPlusPlusOperatorKeyword() && getLangOpts().MicrosoftMode) {
MacroNameTok.setIdentifierInfo(getIdentifierInfo(Spelling));
return;
}
@@ -181,7 +181,7 @@
// trouble than it is worth to insert /**/ and check that there is no /**/
// in the range also.
FixItHint Hint;
- if ((Features.GNUMode || Features.C99 || Features.CPlusPlus) &&
+ if ((LangOpts.GNUMode || LangOpts.C99 || LangOpts.CPlusPlus) &&
!CurTokenLexer)
Hint = FixItHint::CreateInsertion(Tmp.getLocation(),"//");
Diag(Tmp, diag::ext_pp_extra_tokens_at_eol) << DirType << Hint;
@@ -619,7 +619,7 @@
setCodeCompletionReached();
return;
case tok::numeric_constant: // # 7 GNU line marker directive.
- if (getLangOptions().AsmPreprocessor)
+ if (getLangOpts().AsmPreprocessor)
break; // # 4 is not a preprocessor directive in .S files.
return HandleDigitDirective(Result);
default:
@@ -690,12 +690,12 @@
break;
case tok::pp___public_macro:
- if (getLangOptions().Modules)
+ if (getLangOpts().Modules)
return HandleMacroPublicDirective(Result);
break;
case tok::pp___private_macro:
- if (getLangOptions().Modules)
+ if (getLangOpts().Modules)
return HandleMacroPrivateDirective(Result);
break;
}
@@ -706,7 +706,7 @@
// directives. This is important because # may be a comment or introduce
// various pseudo-ops. Just return the # token and push back the following
// token to be lexed next time.
- if (getLangOptions().AsmPreprocessor) {
+ if (getLangOpts().AsmPreprocessor) {
Token *Toks = new Token[2];
// Return the # and the token after it.
Toks[0] = SavedHash;
@@ -805,11 +805,11 @@
// Enforce C99 6.10.4p3: "The digit sequence shall not specify ... a
// number greater than 2147483647". C90 requires that the line # be <= 32767.
unsigned LineLimit = 32768U;
- if (Features.C99 || Features.CPlusPlus0x)
+ if (LangOpts.C99 || LangOpts.CPlusPlus0x)
LineLimit = 2147483648U;
if (LineNo >= LineLimit)
Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit;
- else if (Features.CPlusPlus0x && LineNo >= 32768U)
+ else if (LangOpts.CPlusPlus0x && LineNo >= 32768U)
Diag(DigitTok, diag::warn_cxx98_compat_pp_line_too_big);
int FilenameID = -1;
@@ -1334,7 +1334,7 @@
const FileEntry *File = LookupFile(
Filename, isAngled, LookupFrom, CurDir,
Callbacks ? &SearchPath : NULL, Callbacks ? &RelativePath : NULL,
- getLangOptions().Modules? &SuggestedModule : 0);
+ getLangOpts().Modules? &SuggestedModule : 0);
if (Callbacks) {
if (!File) {
@@ -1348,7 +1348,7 @@
// Try the lookup again, skipping the cache.
File = LookupFile(Filename, isAngled, LookupFrom, CurDir, 0, 0,
- getLangOptions().Modules? &SuggestedModule : 0,
+ getLangOpts().Modules? &SuggestedModule : 0,
/*SkipCache*/true);
}
}
@@ -1410,9 +1410,9 @@
// Determine whether we are actually building the module that this
// include directive maps to.
bool BuildingImportedModule
- = Path[0].first->getName() == getLangOptions().CurrentModule;
+ = Path[0].first->getName() == getLangOpts().CurrentModule;
- if (!BuildingImportedModule && getLangOptions().ObjC2) {
+ if (!BuildingImportedModule && getLangOpts().ObjC2) {
// If we're not building the imported module, warn that we're going
// to automatically turn this inclusion directive into a module import.
// We only do this in Objective-C, where we have a module-import syntax.
@@ -1484,13 +1484,29 @@
return HandleIncludeDirective(HashLoc, IncludeNextTok, Lookup);
}
+/// HandleMicrosoftImportDirective - Implements #import for Microsoft Mode
+void Preprocessor::HandleMicrosoftImportDirective(Token &Tok) {
+ // The Microsoft #import directive takes a type library and generates header
+ // files from it, and includes those. This is beyond the scope of what clang
+ // does, so we ignore it and error out. However, #import can optionally have
+ // trailing attributes that span multiple lines. We're going to eat those
+ // so we can continue processing from there.
+ Diag(Tok, diag::err_pp_import_directive_ms );
+
+ // Read tokens until we get to the end of the directive. Note that the
+ // directive can be split over multiple lines using the backslash character.
+ DiscardUntilEndOfDirective();
+}
+
/// HandleImportDirective - Implements #import.
///
void Preprocessor::HandleImportDirective(SourceLocation HashLoc,
Token &ImportTok) {
- if (!Features.ObjC1) // #import is standard for ObjC.
+ if (!LangOpts.ObjC1) { // #import is standard for ObjC.
+ if (LangOpts.MicrosoftMode)
+ return HandleMicrosoftImportDirective(ImportTok);
Diag(ImportTok, diag::ext_pp_import_directive);
-
+ }
return HandleIncludeDirective(HashLoc, ImportTok, 0, true);
}
@@ -1544,8 +1560,8 @@
Diag(Tok, diag::err_pp_expected_ident_in_arg_list);
return true;
case tok::ellipsis: // #define X(... -> C99 varargs
- if (!Features.C99)
- Diag(Tok, Features.CPlusPlus0x ?
+ if (!LangOpts.C99)
+ Diag(Tok, LangOpts.CPlusPlus0x ?
diag::warn_cxx98_compat_variadic_macro :
diag::ext_variadic_macro);
@@ -1671,7 +1687,7 @@
// Read the first token after the arg list for down below.
LexUnexpandedToken(Tok);
- } else if (Features.C99 || Features.CPlusPlus0x) {
+ } else if (LangOpts.C99 || LangOpts.CPlusPlus0x) {
// C99 requires whitespace between the macro definition and the body. Emit
// a diagnostic for something like "#define X+".
Diag(Tok, diag::ext_c99_whitespace_required_after_macro_name);
@@ -1736,7 +1752,7 @@
// the '#' because '#' is often a comment character. However, change
// the kind of the token to tok::unknown so that the preprocessor isn't
// confused.
- if (getLangOptions().AsmPreprocessor && Tok.isNot(tok::eod)) {
+ if (getLangOpts().AsmPreprocessor && Tok.isNot(tok::eod)) {
LastTok.setKind(tok::unknown);
} else {
Diag(Tok, diag::err_pp_stringize_not_parameter);
Modified: cfe/branches/tooling/lib/Lex/PPExpressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Lex/PPExpressions.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Lex/PPExpressions.cpp (original)
+++ cfe/branches/tooling/lib/Lex/PPExpressions.cpp Mon Mar 19 14:02:20 2012
@@ -220,8 +220,8 @@
PP.Diag(PeekTok, diag::err_pp_invalid_udl) << /*integer*/1;
// long long is a C99 feature.
- if (!PP.getLangOptions().C99 && Literal.isLongLong)
- PP.Diag(PeekTok, PP.getLangOptions().CPlusPlus0x ?
+ if (!PP.getLangOpts().C99 && Literal.isLongLong)
+ PP.Diag(PeekTok, PP.getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_longlong : diag::ext_longlong);
// Parse the integer literal into Result.
@@ -290,7 +290,7 @@
Val = Literal.getValue();
// Set the signedness. UTF-16 and UTF-32 are always unsigned
if (!Literal.isUTF16() && !Literal.isUTF32())
- Val.setIsUnsigned(!PP.getLangOptions().CharIsSigned);
+ Val.setIsUnsigned(!PP.getLangOpts().CharIsSigned);
if (Result.Val.getBitWidth() > Val.getBitWidth()) {
Result.Val = Val.extend(Result.Val.getBitWidth());
@@ -654,7 +654,7 @@
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)
+ if (!PP.getLangOpts().C99 || ValueLive)
PP.Diag(OpLoc, diag::ext_pp_comma_expr)
<< LHS.getRange() << RHS.getRange();
Res = RHS.Val; // LHS = LHS,RHS -> RHS.
Modified: cfe/branches/tooling/lib/Lex/PPLexerChange.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Lex/PPLexerChange.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Lex/PPLexerChange.cpp (original)
+++ cfe/branches/tooling/lib/Lex/PPLexerChange.cpp Mon Mar 19 14:02:20 2012
@@ -328,15 +328,17 @@
CurLexer->BufferPtr = EndPos;
CurLexer->FormTokenWithChars(Result, EndPos, tok::eof);
- // We're done with the #included file.
- CurLexer.reset();
+ if (!isIncrementalProcessingEnabled())
+ // We're done with lexing.
+ CurLexer.reset();
} else {
assert(CurPTHLexer && "Got EOF but no current lexer set!");
CurPTHLexer->getEOF(Result);
CurPTHLexer.reset();
}
-
- CurPPLexer = 0;
+
+ if (!isIncrementalProcessingEnabled())
+ CurPPLexer = 0;
// This is the end of the top-level file. 'WarnUnusedMacroLocs' has collected
// all macro locations that we need to warn because they are not used.
Modified: cfe/branches/tooling/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Lex/PPMacroExpansion.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/branches/tooling/lib/Lex/PPMacroExpansion.cpp Mon Mar 19 14:02:20 2012
@@ -101,7 +101,7 @@
Ident__has_warning = RegisterBuiltinMacro(*this, "__has_warning");
// Microsoft Extensions.
- if (Features.MicrosoftExt)
+ if (LangOpts.MicrosoftExt)
Ident__pragma = RegisterBuiltinMacro(*this, "__pragma");
else
Ident__pragma = 0;
@@ -433,8 +433,8 @@
// Empty arguments are standard in C99 and C++0x, and are supported as an extension in
// other modes.
- if (ArgTokens.size() == ArgTokenStart && !Features.C99)
- Diag(Tok, Features.CPlusPlus0x ?
+ if (ArgTokens.size() == ArgTokenStart && !LangOpts.C99)
+ Diag(Tok, LangOpts.CPlusPlus0x ?
diag::warn_cxx98_compat_empty_fnmacro_arg :
diag::ext_empty_fnmacro_arg);
@@ -588,7 +588,7 @@
/// HasFeature - Return true if we recognize and implement the feature
/// specified by the identifier as a standard language feature.
static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
- const LangOptions &LangOpts = PP.getLangOptions();
+ const LangOptions &LangOpts = PP.getLangOpts();
StringRef Feature = II->getName();
// Normalize the feature name, __foo__ becomes foo.
@@ -640,7 +640,7 @@
.Case("c_atomic", LangOpts.C11)
.Case("c_generic_selections", LangOpts.C11)
.Case("c_static_assert", LangOpts.C11)
- // C++0x features
+ // C++11 features
.Case("cxx_access_control_sfinae", LangOpts.CPlusPlus0x)
.Case("cxx_alias_templates", LangOpts.CPlusPlus0x)
.Case("cxx_alignas", LangOpts.CPlusPlus0x)
@@ -672,7 +672,7 @@
.Case("cxx_trailing_return", LangOpts.CPlusPlus0x)
.Case("cxx_unicode_literals", LangOpts.CPlusPlus0x)
.Case("cxx_unrestricted_unions", LangOpts.CPlusPlus0x)
- //.Case("cxx_user_literals", false)
+ .Case("cxx_user_literals", LangOpts.CPlusPlus0x)
.Case("cxx_variadic_templates", LangOpts.CPlusPlus0x)
// Type traits
.Case("has_nothrow_assign", LangOpts.CPlusPlus)
@@ -732,7 +732,7 @@
DiagnosticsEngine::Ext_Error)
return false;
- const LangOptions &LangOpts = PP.getLangOptions();
+ const LangOptions &LangOpts = PP.getLangOpts();
StringRef Extension = II->getName();
// Normalize the extension name, __foo__ becomes foo.
Modified: cfe/branches/tooling/lib/Lex/Pragma.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Lex/Pragma.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Lex/Pragma.cpp (original)
+++ cfe/branches/tooling/lib/Lex/Pragma.cpp Mon Mar 19 14:02:20 2012
@@ -1230,7 +1230,7 @@
AddPragmaHandler("STDC", new PragmaSTDC_UnknownHandler());
// MS extensions.
- if (Features.MicrosoftExt) {
+ if (LangOpts.MicrosoftExt) {
AddPragmaHandler(new PragmaCommentHandler());
AddPragmaHandler(new PragmaIncludeAliasHandler());
}
Modified: cfe/branches/tooling/lib/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Lex/Preprocessor.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Lex/Preprocessor.cpp (original)
+++ cfe/branches/tooling/lib/Lex/Preprocessor.cpp Mon Mar 19 14:02:20 2012
@@ -54,18 +54,19 @@
HeaderSearch &Headers, ModuleLoader &TheModuleLoader,
IdentifierInfoLookup* IILookup,
bool OwnsHeaders,
- bool DelayInitialization)
- : Diags(&diags), Features(opts), Target(target),FileMgr(Headers.getFileMgr()),
+ bool DelayInitialization,
+ bool IncrProcessing)
+ : Diags(&diags), LangOpts(opts), Target(target),FileMgr(Headers.getFileMgr()),
SourceMgr(SM), HeaderInfo(Headers), TheModuleLoader(TheModuleLoader),
- ExternalSource(0),
- Identifiers(opts, IILookup), CodeComplete(0),
+ ExternalSource(0), Identifiers(opts, IILookup),
+ IncrementalProcessing(IncrProcessing), CodeComplete(0),
CodeCompletionFile(0), CodeCompletionOffset(0), CodeCompletionReached(0),
SkipMainFilePreamble(0, true), CurPPLexer(0),
CurDirLookup(0), CurLexerKind(CLK_Lexer), Callbacks(0), MacroArgCache(0),
Record(0), MIChainHead(0), MICache(0)
{
OwnsHeaderSearch = OwnsHeaders;
-
+
if (!DelayInitialization) {
assert(Target && "Must provide target information for PP initialization");
Initialize(*Target);
@@ -153,7 +154,7 @@
// Initialize builtin macros like __LINE__ and friends.
RegisterBuiltinMacros();
- if(Features.Borland) {
+ if(LangOpts.Borland) {
Ident__exception_info = getIdentifierInfo("_exception_info");
Ident___exception_info = getIdentifierInfo("__exception_info");
Ident_GetExceptionInfo = getIdentifierInfo("GetExceptionInformation");
@@ -382,10 +383,10 @@
}
Module *Preprocessor::getCurrentModule() {
- if (getLangOptions().CurrentModule.empty())
+ if (getLangOpts().CurrentModule.empty())
return 0;
- return getHeaderSearchInfo().lookupModule(getLangOptions().CurrentModule);
+ return getHeaderSearchInfo().lookupModule(getLangOpts().CurrentModule);
}
//===----------------------------------------------------------------------===//
@@ -572,7 +573,7 @@
// keyword when we're in a caching lexer, because caching lexers only get
// used in contexts where import declarations are disallowed.
if (II.isModulesImport() && !InMacroArgs && !DisableMacroExpansion &&
- getLangOptions().Modules && CurLexerKind != CLK_CachingLexer) {
+ getLangOpts().Modules && CurLexerKind != CLK_CachingLexer) {
ModuleImportLoc = Identifier.getLocation();
ModuleImportPath.clear();
ModuleImportExpectsIdentifier = true;
Modified: cfe/branches/tooling/lib/Lex/TokenConcatenation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Lex/TokenConcatenation.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Lex/TokenConcatenation.cpp (original)
+++ cfe/branches/tooling/lib/Lex/TokenConcatenation.cpp Mon Mar 19 14:02:20 2012
@@ -45,7 +45,7 @@
/// IsIdentifierStringPrefix - Return true if the spelling of the token
/// is literally 'L', 'u', 'U', or 'u8'. Including raw versions.
bool TokenConcatenation::IsIdentifierStringPrefix(const Token &Tok) const {
- const LangOptions &LangOpts = PP.getLangOptions();
+ const LangOptions &LangOpts = PP.getLangOpts();
if (!Tok.needsCleaning()) {
if (Tok.getLength() < 1 || Tok.getLength() > 3)
@@ -86,7 +86,7 @@
TokenInfo[tok::arrow ] |= aci_custom_firstchar;
// These tokens have custom code in C++11 mode.
- if (PP.getLangOptions().CPlusPlus0x) {
+ if (PP.getLangOpts().CPlusPlus0x) {
TokenInfo[tok::string_literal ] |= aci_custom;
TokenInfo[tok::wide_string_literal ] |= aci_custom;
TokenInfo[tok::utf8_string_literal ] |= aci_custom;
@@ -205,7 +205,7 @@
case tok::wide_char_constant:
case tok::utf16_char_constant:
case tok::utf32_char_constant:
- if (!PP.getLangOptions().CPlusPlus0x)
+ if (!PP.getLangOpts().CPlusPlus0x)
return false;
// In C++11, a string or character literal followed by an identifier is a
@@ -240,11 +240,11 @@
case tok::numeric_constant:
return isalnum(FirstChar) || Tok.is(tok::numeric_constant) ||
FirstChar == '+' || FirstChar == '-' || FirstChar == '.' ||
- (PP.getLangOptions().CPlusPlus0x && FirstChar == '_');
+ (PP.getLangOpts().CPlusPlus0x && FirstChar == '_');
case tok::period: // ..., .*, .1234
return (FirstChar == '.' && PrevPrevTok.is(tok::period)) ||
isdigit(FirstChar) ||
- (PP.getLangOptions().CPlusPlus && FirstChar == '*');
+ (PP.getLangOpts().CPlusPlus && FirstChar == '*');
case tok::amp: // &&
return FirstChar == '&';
case tok::plus: // ++
@@ -263,10 +263,10 @@
return FirstChar == '>' || FirstChar == ':';
case tok::colon: // ::, :>
return FirstChar == '>' ||
- (PP.getLangOptions().CPlusPlus && FirstChar == ':');
+ (PP.getLangOpts().CPlusPlus && FirstChar == ':');
case tok::hash: // ##, #@, %:%:
return FirstChar == '#' || FirstChar == '@' || FirstChar == '%';
case tok::arrow: // ->*
- return PP.getLangOptions().CPlusPlus && FirstChar == '*';
+ return PP.getLangOpts().CPlusPlus && FirstChar == '*';
}
}
Modified: cfe/branches/tooling/lib/Lex/TokenLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Lex/TokenLexer.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Lex/TokenLexer.cpp (original)
+++ cfe/branches/tooling/lib/Lex/TokenLexer.cpp Mon Mar 19 14:02:20 2012
@@ -527,7 +527,7 @@
// Make a lexer to lex this string from. Lex just this one token.
// Make a lexer object so that we lex and expand the paste result.
Lexer TL(SourceMgr.getLocForStartOfFile(LocFileID),
- PP.getLangOptions(), ScratchBufStart,
+ PP.getLangOpts(), ScratchBufStart,
ResultTokStrPtr, ResultTokStrPtr+LHSLen+RHSLen);
// Lex a token in raw mode. This way it won't look up identifiers
@@ -546,14 +546,14 @@
if (isInvalid) {
// Test for the Microsoft extension of /##/ turning into // here on the
// error path.
- if (PP.getLangOptions().MicrosoftExt && Tok.is(tok::slash) &&
+ if (PP.getLangOpts().MicrosoftExt && Tok.is(tok::slash) &&
RHS.is(tok::slash)) {
HandleMicrosoftCommentPaste(Tok);
return true;
}
// Do not emit the error when preprocessing assembler code.
- if (!PP.getLangOptions().AsmPreprocessor) {
+ if (!PP.getLangOpts().AsmPreprocessor) {
// Explicitly convert the token location to have proper expansion
// information so that the user knows where it came from.
SourceManager &SM = PP.getSourceManager();
@@ -563,7 +563,7 @@
// error to a warning that defaults to an error. This allows
// disabling it.
PP.Diag(Loc,
- PP.getLangOptions().MicrosoftExt ? diag::err_pp_bad_paste_ms
+ PP.getLangOpts().MicrosoftExt ? diag::err_pp_bad_paste_ms
: diag::err_pp_bad_paste)
<< Buffer.str();
}
Modified: cfe/branches/tooling/lib/Parse/ParseCXXInlineMethods.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseCXXInlineMethods.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseCXXInlineMethods.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseCXXInlineMethods.cpp Mon Mar 19 14:02:20 2012
@@ -74,7 +74,7 @@
bool Delete = false;
SourceLocation KWLoc;
if (Tok.is(tok::kw_delete)) {
- Diag(Tok, getLang().CPlusPlus0x ?
+ Diag(Tok, getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_deleted_function :
diag::ext_deleted_function);
@@ -82,7 +82,7 @@
Actions.SetDeclDeleted(FnD, KWLoc);
Delete = true;
} else if (Tok.is(tok::kw_default)) {
- Diag(Tok, getLang().CPlusPlus0x ?
+ Diag(Tok, getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_defaulted_function :
diag::ext_defaulted_function);
@@ -107,7 +107,7 @@
// In delayed template parsing mode, if we are within a class template
// or if we are about to parse function member template then consume
// the tokens and store them for parsing at the end of the translation unit.
- if (getLang().DelayedTemplateParsing &&
+ if (getLangOpts().DelayedTemplateParsing &&
((Actions.CurContext->isDependentContext() ||
TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) &&
!Actions.IsInsideALocalClassWithinATemplateFunction())) {
@@ -319,7 +319,11 @@
Sema::PotentiallyEvaluatedIfUsed,
LM.DefaultArgs[I].Param);
- ExprResult DefArgResult(ParseAssignmentExpression());
+ ExprResult DefArgResult;
+ if (Tok.is(tok::l_brace))
+ DefArgResult = ParseBraceInitializer();
+ else
+ DefArgResult = ParseAssignmentExpression();
if (DefArgResult.isInvalid())
Actions.ActOnParamDefaultArgumentError(LM.DefaultArgs[I].Param);
else {
@@ -632,7 +636,7 @@
ConsumeBrace();
// In C++03, this has to be the start of the function body, which
// means the initializer is malformed; we'll diagnose it later.
- if (!getLang().CPlusPlus0x)
+ if (!getLangOpts().CPlusPlus0x)
return false;
}
Modified: cfe/branches/tooling/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseDecl.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseDecl.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseDecl.cpp Mon Mar 19 14:02:20 2012
@@ -36,9 +36,11 @@
Declarator::TheContext Context,
AccessSpecifier AS,
Decl **OwnedType) {
+ DeclSpecContext DSC = getDeclSpecContextFromDeclaratorContext(Context);
+
// Parse the common declaration-specifiers piece.
DeclSpec DS(AttrFactory);
- ParseSpecifierQualifierList(DS, AS);
+ ParseSpecifierQualifierList(DS, AS, DSC);
if (OwnedType)
*OwnedType = DS.isTypeSpecOwned() ? DS.getRepAsDecl() : 0;
@@ -536,7 +538,7 @@
/// version-arg:
/// 'introduced' '=' version
/// 'deprecated' '=' version
-/// 'removed' = version
+/// 'obsoleted' = version
/// 'unavailable'
/// opt-message:
/// 'message' '=' <string>
@@ -934,7 +936,7 @@
break;
case tok::kw_inline:
// Could be the start of an inline namespace. Allowed as an ext in C++03.
- if (getLang().CPlusPlus && NextToken().is(tok::kw_namespace)) {
+ if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_namespace)) {
ProhibitAttributes(attrs);
SourceLocation InlineLoc = ConsumeToken();
SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc);
@@ -1023,14 +1025,14 @@
case tok::amp:
case tok::ampamp:
- return getLang().CPlusPlus;
+ return getLangOpts().CPlusPlus;
case tok::l_square: // Might be an attribute on an unnamed bit-field.
- return Context == Declarator::MemberContext && getLang().CPlusPlus0x &&
+ return Context == Declarator::MemberContext && getLangOpts().CPlusPlus0x &&
NextToken().is(tok::l_square);
case tok::colon: // Might be a typo for '::' or an unnamed bit-field.
- return Context == Declarator::MemberContext || getLang().CPlusPlus;
+ return Context == Declarator::MemberContext || getLangOpts().CPlusPlus;
case tok::identifier:
switch (NextToken().getKind()) {
@@ -1057,10 +1059,10 @@
// and in block scope it's probably a label. Inside a class definition,
// this is a bit-field.
return Context == Declarator::MemberContext ||
- (getLang().CPlusPlus && Context == Declarator::FileContext);
+ (getLangOpts().CPlusPlus && Context == Declarator::FileContext);
case tok::identifier: // Possible virt-specifier.
- return getLang().CPlusPlus0x && isCXX0XVirtSpecifier(NextToken());
+ return getLangOpts().CPlusPlus0x && isCXX0XVirtSpecifier(NextToken());
default:
return false;
@@ -1324,7 +1326,7 @@
else
Diag(ConsumeToken(), diag::err_default_special_members);
} else {
- if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
+ if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
EnterScope(0);
Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
}
@@ -1337,7 +1339,7 @@
ExprResult Init(ParseInitializer());
- if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
+ if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
ExitScope();
}
@@ -1357,7 +1359,7 @@
ExprVector Exprs(Actions);
CommaLocsTy CommaLocs;
- if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
+ if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
EnterScope(0);
Actions.ActOnCXXEnterDeclInitializer(getCurScope(), ThisDecl);
}
@@ -1365,7 +1367,7 @@
if (ParseExpressionList(Exprs, CommaLocs)) {
SkipUntil(tok::r_paren);
- if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
+ if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
ExitScope();
}
@@ -1376,7 +1378,7 @@
assert(!Exprs.empty() && Exprs.size()-1 == CommaLocs.size() &&
"Unexpected number of commas!");
- if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) {
+ if (getLangOpts().CPlusPlus && D.getCXXScopeSpec().isSet()) {
Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl);
ExitScope();
}
@@ -1387,7 +1389,7 @@
Actions.AddInitializerToDecl(ThisDecl, Initializer.take(),
/*DirectInit=*/true, TypeContainsAuto);
}
- } else if (getLang().CPlusPlus0x && Tok.is(tok::l_brace)) {
+ } else if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) {
// Parse C++0x braced-init-list.
Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
@@ -1424,17 +1426,24 @@
/// type-qualifier specifier-qualifier-list[opt]
/// [GNU] attributes specifier-qualifier-list[opt]
///
-void Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS) {
+void Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS,
+ DeclSpecContext DSC) {
/// specifier-qualifier-list is a subset of declaration-specifiers. Just
/// parse declaration-specifiers and complain about extra stuff.
/// TODO: diagnose attribute-specifiers and alignment-specifiers.
- ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS);
+ ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC);
// Validate declspec for type-name.
unsigned Specs = DS.getParsedSpecifiers();
- if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() &&
- !DS.hasAttributes())
+ if (DSC == DSC_type_specifier && !DS.hasTypeSpecifier()) {
+ Diag(Tok, diag::err_expected_type);
+ DS.SetTypeSpecError();
+ } else if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() &&
+ !DS.hasAttributes()) {
Diag(Tok, diag::err_typename_requires_specqual);
+ if (!DS.hasTypeSpecifier())
+ DS.SetTypeSpecError();
+ }
// Issue diagnostic and remove storage class if present.
if (Specs & DeclSpec::PQ_StorageClassSpecifier) {
@@ -1455,6 +1464,12 @@
Diag(DS.getExplicitSpecLoc(), diag::err_typename_invalid_functionspec);
DS.ClearFunctionSpecs();
}
+
+ // Issue diagnostic and remove constexpr specfier if present.
+ if (DS.isConstexprSpecified()) {
+ Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr);
+ DS.ClearConstexprSpec();
+ }
}
/// isValidAfterIdentifierInDeclaratorAfterDeclSpec - Return true if the
@@ -1493,7 +1508,7 @@
///
bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
const ParsedTemplateInfo &TemplateInfo,
- AccessSpecifier AS) {
+ AccessSpecifier AS, DeclSpecContext DSC) {
assert(Tok.is(tok::identifier) && "should have identifier");
SourceLocation Loc = Tok.getLocation();
@@ -1512,8 +1527,13 @@
assert(!DS.hasTypeSpecifier() && "Type specifier checked above");
// Since we know that this either implicit int (which is rare) or an
- // error, we'd do lookahead to try to do better recovery.
- if (isValidAfterIdentifierInDeclarator(NextToken())) {
+ // error, do lookahead to try to do better recovery. This never applies within
+ // a type specifier.
+ // FIXME: Don't bail out here in languages with no implicit int (like
+ // C++ with no -fms-extensions). This is much more likely to be an undeclared
+ // type or typo than a use of implicit int.
+ if (DSC != DSC_type_specifier &&
+ isValidAfterIdentifierInDeclarator(NextToken())) {
// If this token is valid for implicit int, e.g. "static x = 4", then
// we just avoid eating the identifier, so it will be parsed as the
// identifier in the declarator.
@@ -1544,14 +1564,15 @@
if (TagName) {
Diag(Loc, diag::err_use_of_tag_name_without_tag)
- << Tok.getIdentifierInfo() << TagName << getLang().CPlusPlus
+ << Tok.getIdentifierInfo() << TagName << getLangOpts().CPlusPlus
<< FixItHint::CreateInsertion(Tok.getLocation(),FixitTagName);
// Parse this as a tag as if the missing tag were present.
if (TagKind == tok::kw_enum)
- ParseEnumSpecifier(Loc, DS, TemplateInfo, AS);
+ ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSC_normal);
else
- ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS);
+ ParseClassSpecifier(TagKind, Loc, DS, TemplateInfo, AS,
+ /*EnteringContext*/ false, DSC_normal);
return true;
}
}
@@ -1585,9 +1606,7 @@
}
// Mark this as an error.
- const char *PrevSpec;
- unsigned DiagID;
- DS.SetTypeSpecType(DeclSpec::TST_error, Loc, PrevSpec, DiagID);
+ DS.SetTypeSpecError();
DS.SetRangeEnd(Tok.getLocation());
ConsumeToken();
@@ -1608,6 +1627,8 @@
return DSC_class;
if (Context == Declarator::FileContext)
return DSC_top_level;
+ if (Context == Declarator::TrailingReturnContext)
+ return DSC_trailing;
return DSC_normal;
}
@@ -1632,7 +1653,7 @@
} else
ER = ParseConstantExpression();
- if (getLang().CPlusPlus0x && Tok.is(tok::ellipsis))
+ if (getLangOpts().CPlusPlus0x && Tok.is(tok::ellipsis))
EllipsisLoc = ConsumeToken();
return ER;
@@ -1895,7 +1916,7 @@
// typename.
if (TypeRep == 0) {
ConsumeToken(); // Eat the scope spec so the identifier is current.
- if (ParseImplicitInt(DS, &SS, TemplateInfo, AS)) continue;
+ if (ParseImplicitInt(DS, &SS, TemplateInfo, AS, DSContext)) continue;
goto DoneWithDeclSpec;
}
@@ -1930,7 +1951,7 @@
// Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
// is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
// Objective-C interface.
- if (Tok.is(tok::less) && getLang().ObjC1)
+ if (Tok.is(tok::less) && getLangOpts().ObjC1)
ParseObjCProtocolQualifiers(DS);
continue;
@@ -1959,7 +1980,7 @@
case tok::identifier: {
// In C++, check to see if this is a scope specifier like foo::bar::, if
// so handle it as such. This is important for ctor parsing.
- if (getLang().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
if (TryAnnotateCXXScopeToken(true)) {
if (!DS.hasTypeSpecifier())
DS.SetTypeSpecError();
@@ -1979,7 +2000,6 @@
if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
break;
- // It has to be available as a typedef too!
ParsedType TypeRep =
Actions.getTypeName(*Tok.getIdentifierInfo(),
Tok.getLocation(), getCurScope());
@@ -1987,13 +2007,13 @@
// If this is not a typedef name, don't parse it as part of the declspec,
// it must be an implicit int or an error.
if (!TypeRep) {
- if (ParseImplicitInt(DS, 0, TemplateInfo, AS)) continue;
+ if (ParseImplicitInt(DS, 0, TemplateInfo, AS, DSContext)) continue;
goto DoneWithDeclSpec;
}
// If we're in a context where the identifier could be a class name,
// check whether this is a constructor declaration.
- if (getLang().CPlusPlus && DSContext == DSC_class &&
+ if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
Actions.isCurrentClassName(*Tok.getIdentifierInfo(), getCurScope()) &&
isConstructorDeclarator())
goto DoneWithDeclSpec;
@@ -2009,7 +2029,7 @@
// Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
// is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
// Objective-C interface.
- if (Tok.is(tok::less) && getLang().ObjC1)
+ if (Tok.is(tok::less) && getLangOpts().ObjC1)
ParseObjCProtocolQualifiers(DS);
// Need to support trailing type qualifiers (e.g. "id<p> const").
@@ -2029,7 +2049,7 @@
// If we're in a context where the template-id could be a
// constructor name or specialization, check whether this is a
// constructor declaration.
- if (getLang().CPlusPlus && DSContext == DSC_class &&
+ if (getLangOpts().CPlusPlus && DSContext == DSC_class &&
Actions.isCurrentClassName(*TemplateId->Name, getCurScope()) &&
isConstructorDeclarator())
goto DoneWithDeclSpec;
@@ -2098,7 +2118,7 @@
PrevSpec, DiagID);
break;
case tok::kw_auto:
- if (getLang().CPlusPlus0x) {
+ if (getLangOpts().CPlusPlus0x) {
if (isKnownToBeTypeSpecifier(GetLookAheadToken(1))) {
isInvalid = DS.SetStorageClassSpec(Actions, DeclSpec::SCS_auto, Loc,
PrevSpec, DiagID);
@@ -2137,7 +2157,7 @@
// alignment-specifier
case tok::kw__Alignas:
- if (!getLang().C11)
+ if (!getLangOpts().C11)
Diag(Tok, diag::ext_c11_alignas);
ParseAlignmentSpecifier(DS.getAttributes());
continue;
@@ -2276,28 +2296,29 @@
case tok::kw_union: {
tok::TokenKind Kind = Tok.getKind();
ConsumeToken();
- ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS, EnteringContext);
+ ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS,
+ EnteringContext, DSContext);
continue;
}
// enum-specifier:
case tok::kw_enum:
ConsumeToken();
- ParseEnumSpecifier(Loc, DS, TemplateInfo, AS);
+ ParseEnumSpecifier(Loc, DS, TemplateInfo, AS, DSContext);
continue;
// cv-qualifier:
case tok::kw_const:
isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID,
- getLang());
+ getLangOpts());
break;
case tok::kw_volatile:
isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
- getLang());
+ getLangOpts());
break;
case tok::kw_restrict:
isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
- getLang());
+ getLangOpts());
break;
// C++ typename-specifier:
@@ -2329,7 +2350,7 @@
// OpenCL qualifiers:
case tok::kw_private:
- if (!getLang().OpenCL)
+ if (!getLangOpts().OpenCL)
goto DoneWithDeclSpec;
case tok::kw___private:
case tok::kw___global:
@@ -2345,7 +2366,7 @@
// GCC ObjC supports types like "<SomeProtocol>" as a synonym for
// "id<SomeProtocol>". This is hopelessly old fashioned and dangerous,
// but we support it.
- if (DS.hasTypeSpecifier() || !getLang().ObjC1)
+ if (DS.hasTypeSpecifier() || !getLangOpts().ObjC1)
goto DoneWithDeclSpec;
if (!ParseObjCProtocolQualifiers(DS))
@@ -2375,301 +2396,6 @@
}
}
-/// ParseOptionalTypeSpecifier - Try to parse a single type-specifier. We
-/// primarily follow the C++ grammar with additions for C99 and GNU,
-/// which together subsume the C grammar. Note that the C++
-/// type-specifier also includes the C type-qualifier (for const,
-/// volatile, and C99 restrict). Returns true if a type-specifier was
-/// found (and parsed), false otherwise.
-///
-/// type-specifier: [C++ 7.1.5]
-/// simple-type-specifier
-/// class-specifier
-/// enum-specifier
-/// elaborated-type-specifier [TODO]
-/// cv-qualifier
-///
-/// cv-qualifier: [C++ 7.1.5.1]
-/// 'const'
-/// 'volatile'
-/// [C99] 'restrict'
-///
-/// simple-type-specifier: [ C++ 7.1.5.2]
-/// '::'[opt] nested-name-specifier[opt] type-name [TODO]
-/// '::'[opt] nested-name-specifier 'template' template-id [TODO]
-/// 'char'
-/// 'wchar_t'
-/// 'bool'
-/// 'short'
-/// 'int'
-/// 'long'
-/// 'signed'
-/// 'unsigned'
-/// 'float'
-/// 'double'
-/// 'void'
-/// [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]
-/// [C++0x] 'decltype' ( expression )
-/// [AltiVec] '__vector'
-bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid,
- const char *&PrevSpec,
- unsigned &DiagID,
- const ParsedTemplateInfo &TemplateInfo,
- bool SuppressDeclarations) {
- SourceLocation Loc = Tok.getLocation();
-
- switch (Tok.getKind()) {
- case tok::identifier: // foo::bar
- // If we already have a type specifier, this identifier is not a type.
- if (DS.getTypeSpecType() != DeclSpec::TST_unspecified ||
- DS.getTypeSpecWidth() != DeclSpec::TSW_unspecified ||
- DS.getTypeSpecSign() != DeclSpec::TSS_unspecified)
- return false;
- // Check for need to substitute AltiVec keyword tokens.
- if (TryAltiVecToken(DS, Loc, PrevSpec, DiagID, isInvalid))
- break;
- // Fall through.
- case tok::kw_decltype:
- case tok::kw_typename: // typename foo::bar
- // Annotate typenames and C++ scope specifiers. If we get one, just
- // recurse to handle whatever we get.
- if (TryAnnotateTypeOrScopeToken(/*EnteringContext=*/false,
- /*NeedType=*/true))
- return true;
- if (Tok.is(tok::identifier))
- return false;
- return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
- TemplateInfo, SuppressDeclarations);
- case tok::coloncolon: // ::foo::bar
- if (NextToken().is(tok::kw_new) || // ::new
- NextToken().is(tok::kw_delete)) // ::delete
- return false;
-
- // Annotate typenames and C++ scope specifiers. If we get one, just
- // recurse to handle whatever we get.
- if (TryAnnotateTypeOrScopeToken(/*EnteringContext=*/false,
- /*NeedType=*/true))
- return true;
- return ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
- TemplateInfo, SuppressDeclarations);
-
- // simple-type-specifier:
- case tok::annot_typename: {
- if (ParsedType T = getTypeAnnotation(Tok)) {
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename,
- Tok.getAnnotationEndLoc(), PrevSpec,
- DiagID, T);
- } else
- DS.SetTypeSpecError();
- DS.SetRangeEnd(Tok.getAnnotationEndLoc());
- ConsumeToken(); // The typename
-
- // Objective-C supports syntax of the form 'id<proto1,proto2>' where 'id'
- // is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
- // Objective-C interface. If we don't have Objective-C or a '<', this is
- // just a normal reference to a typedef name.
- if (Tok.is(tok::less) && getLang().ObjC1)
- ParseObjCProtocolQualifiers(DS);
-
- return true;
- }
-
- case tok::kw_short:
- isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec, DiagID);
- break;
- case tok::kw_long:
- if (DS.getTypeSpecWidth() != DeclSpec::TSW_long)
- isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_long, Loc, PrevSpec,
- DiagID);
- else
- isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
- DiagID);
- break;
- case tok::kw___int64:
- isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_longlong, Loc, PrevSpec,
- DiagID);
- break;
- case tok::kw_signed:
- isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_signed, Loc, PrevSpec, DiagID);
- break;
- case tok::kw_unsigned:
- isInvalid = DS.SetTypeSpecSign(DeclSpec::TSS_unsigned, Loc, PrevSpec,
- DiagID);
- break;
- case tok::kw__Complex:
- isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_complex, Loc, PrevSpec,
- DiagID);
- break;
- case tok::kw__Imaginary:
- isInvalid = DS.SetTypeSpecComplex(DeclSpec::TSC_imaginary, Loc, PrevSpec,
- DiagID);
- break;
- case tok::kw_void:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID);
- break;
- case tok::kw_char:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID);
- break;
- case tok::kw_int:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, PrevSpec, DiagID);
- break;
- case tok::kw_half:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_half, Loc, PrevSpec, DiagID);
- break;
- case tok::kw_float:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float, Loc, PrevSpec, DiagID);
- break;
- case tok::kw_double:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID);
- break;
- case tok::kw_wchar_t:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID);
- break;
- case tok::kw_char16_t:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID);
- break;
- case tok::kw_char32_t:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec, DiagID);
- break;
- case tok::kw_bool:
- case tok::kw__Bool:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID);
- break;
- case tok::kw__Decimal32:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal32, Loc, PrevSpec,
- DiagID);
- break;
- case tok::kw__Decimal64:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal64, Loc, PrevSpec,
- DiagID);
- break;
- case tok::kw__Decimal128:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_decimal128, Loc, PrevSpec,
- DiagID);
- break;
- case tok::kw___vector:
- isInvalid = DS.SetTypeAltiVecVector(true, Loc, PrevSpec, DiagID);
- break;
- case tok::kw___pixel:
- isInvalid = DS.SetTypeAltiVecPixel(true, Loc, PrevSpec, DiagID);
- break;
-
- // class-specifier:
- case tok::kw_class:
- case tok::kw_struct:
- case tok::kw_union: {
- tok::TokenKind Kind = Tok.getKind();
- ConsumeToken();
- ParseClassSpecifier(Kind, Loc, DS, TemplateInfo, AS_none,
- /*EnteringContext=*/false,
- SuppressDeclarations);
- return true;
- }
-
- // enum-specifier:
- case tok::kw_enum:
- ConsumeToken();
- ParseEnumSpecifier(Loc, DS, TemplateInfo, AS_none);
- return true;
-
- // cv-qualifier:
- case tok::kw_const:
- isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec,
- DiagID, getLang());
- break;
- case tok::kw_volatile:
- isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec,
- DiagID, getLang());
- break;
- case tok::kw_restrict:
- isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec,
- DiagID, getLang());
- break;
-
- // GNU typeof support.
- case tok::kw_typeof:
- ParseTypeofSpecifier(DS);
- return true;
-
- // C++0x decltype support.
- case tok::annot_decltype:
- ParseDecltypeSpecifier(DS);
- return true;
-
- // C++0x type traits support.
- case tok::kw___underlying_type:
- ParseUnderlyingTypeSpecifier(DS);
- return true;
-
- case tok::kw__Atomic:
- ParseAtomicSpecifier(DS);
- return true;
-
- // OpenCL qualifiers:
- case tok::kw_private:
- if (!getLang().OpenCL)
- return false;
- case tok::kw___private:
- case tok::kw___global:
- case tok::kw___local:
- case tok::kw___constant:
- case tok::kw___read_only:
- case tok::kw___write_only:
- case tok::kw___read_write:
- ParseOpenCLQualifiers(DS);
- break;
-
- // C++0x auto support.
- case tok::kw_auto:
- // This is only called in situations where a storage-class specifier is
- // illegal, so we can assume an auto type specifier was intended even in
- // C++98. In C++98 mode, DeclSpec::Finish will produce an appropriate
- // extension diagnostic.
- if (!getLang().CPlusPlus)
- return false;
-
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec, DiagID);
- break;
-
- case tok::kw___ptr64:
- case tok::kw___ptr32:
- case tok::kw___w64:
- case tok::kw___cdecl:
- case tok::kw___stdcall:
- case tok::kw___fastcall:
- case tok::kw___thiscall:
- case tok::kw___unaligned:
- ParseMicrosoftTypeAttributes(DS.getAttributes());
- return true;
-
- case tok::kw___pascal:
- ParseBorlandTypeAttributes(DS.getAttributes());
- return true;
-
- default:
- // Not a type-specifier; do nothing.
- return false;
- }
-
- // If the specifier combination wasn't legal, issue a diagnostic.
- if (isInvalid) {
- assert(PrevSpec && "Method did not return previous specifier!");
- // Pick between error or extwarn.
- Diag(Tok, DiagID) << PrevSpec;
- }
- DS.SetRangeEnd(Tok.getLocation());
- ConsumeToken(); // whatever we parsed above.
- return true;
-}
-
/// ParseStructDeclaration - Parse a struct declaration without the terminating
/// semicolon.
///
@@ -2779,7 +2505,7 @@
// 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) {
+ if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus) {
Diag(Tok, diag::ext_empty_struct_union) << (TagType == TST_union);
Diag(Tok, diag::warn_empty_struct_union_compat) << (TagType == TST_union);
}
@@ -2905,7 +2631,7 @@
///
void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
const ParsedTemplateInfo &TemplateInfo,
- AccessSpecifier AS) {
+ AccessSpecifier AS, DeclSpecContext DSC) {
// Parse the tag portion of this.
if (Tok.is(tok::code_completion)) {
// Code completion for an enum name.
@@ -2916,7 +2642,7 @@
SourceLocation ScopedEnumKWLoc;
bool IsScopedUsingClassTag = false;
- if (getLang().CPlusPlus0x &&
+ if (getLangOpts().CPlusPlus0x &&
(Tok.is(tok::kw_class) || Tok.is(tok::kw_struct))) {
Diag(Tok, diag::warn_cxx98_compat_scoped_enum);
IsScopedUsingClassTag = Tok.is(tok::kw_class);
@@ -2931,11 +2657,15 @@
while (Tok.is(tok::kw___declspec))
ParseMicrosoftDeclSpec(attrs);
- bool AllowFixedUnderlyingType
- = getLang().CPlusPlus0x || getLang().MicrosoftExt || getLang().ObjC2;
+ // Enum definitions should not be parsed in a trailing-return-type.
+ bool AllowDeclaration = DSC != DSC_trailing;
+
+ bool AllowFixedUnderlyingType = AllowDeclaration &&
+ (getLangOpts().CPlusPlus0x || getLangOpts().MicrosoftExt ||
+ getLangOpts().ObjC2);
CXXScopeSpec &SS = DS.getTypeSpecScope();
- if (getLang().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
// "enum foo : bar;" is not a potential typo for "enum foo::bar;"
// if a fixed underlying type is allowed.
ColonProtectionRAIIObject X(*this, AllowFixedUnderlyingType);
@@ -2957,7 +2687,7 @@
// Must have either 'enum name' or 'enum {...}'.
if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
- (AllowFixedUnderlyingType && Tok.isNot(tok::colon))) {
+ !(AllowFixedUnderlyingType && Tok.is(tok::colon))) {
Diag(Tok, diag::err_expected_ident_lbrace);
// Skip the rest of this declarator, up until the comma or semicolon.
@@ -3022,9 +2752,9 @@
// underlying type.
// FIXME: The standard is not entirely clear on how to disambiguate in
// this case.
- if ((getLang().CPlusPlus &&
+ if ((getLangOpts().CPlusPlus &&
isCXXDeclarationSpecifier(TPResult::True()) != TPResult::True()) ||
- (!getLang().CPlusPlus && !isDeclarationSpecifier(true))) {
+ (!getLangOpts().CPlusPlus && !isDeclarationSpecifier(true))) {
// We'll parse this as a bitfield later.
PossibleBitfield = true;
TPA.Revert();
@@ -3042,10 +2772,10 @@
SourceRange Range;
BaseType = ParseTypeName(&Range);
- if (!getLang().CPlusPlus0x && !getLang().ObjC2)
+ if (!getLangOpts().CPlusPlus0x && !getLangOpts().ObjC2)
Diag(StartLoc, diag::ext_ms_enum_fixed_underlying_type)
<< Range;
- if (getLang().CPlusPlus0x)
+ if (getLangOpts().CPlusPlus0x)
Diag(StartLoc, diag::warn_cxx98_compat_enum_fixed_underlying_type);
}
}
@@ -3063,9 +2793,11 @@
Sema::TagUseKind TUK;
if (DS.isFriendSpecified())
TUK = Sema::TUK_Friend;
+ else if (!AllowDeclaration)
+ TUK = Sema::TUK_Reference;
else if (Tok.is(tok::l_brace))
TUK = Sema::TUK_Definition;
- else if (Tok.is(tok::semi))
+ else if (Tok.is(tok::semi) && DSC != DSC_type_specifier)
TUK = Sema::TUK_Declaration;
else
TUK = Sema::TUK_Reference;
@@ -3128,7 +2860,7 @@
if (!TagDecl) {
// The action failed to produce an enumeration tag. If this is a
// definition, consume the entire definition.
- if (Tok.is(tok::l_brace)) {
+ if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) {
ConsumeBrace();
SkipUntil(tok::r_brace);
}
@@ -3137,7 +2869,7 @@
return;
}
- if (Tok.is(tok::l_brace)) {
+ if (Tok.is(tok::l_brace) && TUK != Sema::TUK_Reference) {
if (TUK == Sema::TUK_Friend)
Diag(Tok, diag::err_friend_decl_defines_type)
<< SourceRange(DS.getFriendSpecLoc());
@@ -3169,7 +2901,7 @@
T.consumeOpen();
// C does not allow an empty enumerator-list, C++ does [dcl.enum].
- if (Tok.is(tok::r_brace) && !getLang().CPlusPlus)
+ if (Tok.is(tok::r_brace) && !getLangOpts().CPlusPlus)
Diag(Tok, diag::error_empty_enum);
SmallVector<Decl *, 32> EnumConstantDecls;
@@ -3220,11 +2952,11 @@
SourceLocation CommaLoc = ConsumeToken();
if (Tok.isNot(tok::identifier)) {
- if (!getLang().C99 && !getLang().CPlusPlus0x)
+ if (!getLangOpts().C99 && !getLangOpts().CPlusPlus0x)
Diag(CommaLoc, diag::ext_enumerator_list_comma)
- << getLang().CPlusPlus
+ << getLangOpts().CPlusPlus
<< FixItHint::CreateRemoval(CommaLoc);
- else if (getLang().CPlusPlus0x)
+ else if (getLangOpts().CPlusPlus0x)
Diag(CommaLoc, diag::warn_cxx98_compat_enumerator_list_comma)
<< FixItHint::CreateRemoval(CommaLoc);
}
@@ -3255,7 +2987,7 @@
// type-qualifier only in OpenCL
case tok::kw_private:
- return getLang().OpenCL;
+ return getLangOpts().OpenCL;
// type-qualifier
case tok::kw_const:
@@ -3390,7 +3122,7 @@
// GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
case tok::less:
- return getLang().ObjC1;
+ return getLangOpts().ObjC1;
case tok::kw___cdecl:
case tok::kw___stdcall:
@@ -3413,7 +3145,7 @@
return true;
case tok::kw_private:
- return getLang().OpenCL;
+ return getLangOpts().OpenCL;
// C11 _Atomic()
case tok::kw__Atomic:
@@ -3431,11 +3163,11 @@
default: return false;
case tok::kw_private:
- return getLang().OpenCL;
+ return getLangOpts().OpenCL;
case tok::identifier: // foo::bar
// Unfortunate hack to support "Class.factoryMethod" notation.
- if (getLang().ObjC1 && NextToken().is(tok::period))
+ if (getLangOpts().ObjC1 && NextToken().is(tok::period))
return false;
if (TryAltiVecVectorToken())
return true;
@@ -3545,7 +3277,7 @@
// GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
case tok::less:
- return getLang().ObjC1;
+ return getLangOpts().ObjC1;
// typedef-name
case tok::annot_typename:
@@ -3642,7 +3374,7 @@
void Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
bool VendorAttributesAllowed,
bool CXX0XAttributesAllowed) {
- if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
+ if (getLangOpts().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
SourceLocation Loc = Tok.getLocation();
ParsedAttributesWithRange attrs(AttrFactory);
ParseCXX0XAttributes(attrs);
@@ -3667,20 +3399,20 @@
case tok::kw_const:
isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, DiagID,
- getLang());
+ getLangOpts());
break;
case tok::kw_volatile:
isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
- getLang());
+ getLangOpts());
break;
case tok::kw_restrict:
isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
- getLang());
+ getLangOpts());
break;
// OpenCL qualifiers:
case tok::kw_private:
- if (!getLang().OpenCL)
+ if (!getLangOpts().OpenCL)
goto DoneWithTypeQuals;
case tok::kw___private:
case tok::kw___global:
@@ -3777,7 +3509,7 @@
// C++ member pointers start with a '::' or a nested-name.
// Member pointers get special handling, since there's no place for the
// scope spec in the generic path below.
- if (getLang().CPlusPlus &&
+ if (getLangOpts().CPlusPlus &&
(Tok.is(tok::coloncolon) || Tok.is(tok::identifier) ||
Tok.is(tok::annot_cxxscope))) {
bool EnteringContext = D.getContext() == Declarator::FileContext ||
@@ -3816,9 +3548,9 @@
tok::TokenKind Kind = Tok.getKind();
// Not a pointer, C++ reference, or block.
if (Kind != tok::star && Kind != tok::caret &&
- (Kind != tok::amp || !getLang().CPlusPlus) &&
+ (Kind != tok::amp || !getLangOpts().CPlusPlus) &&
// We parse rvalue refs in C++03, because otherwise the errors are scary.
- (Kind != tok::ampamp || !getLang().CPlusPlus)) {
+ (Kind != tok::ampamp || !getLangOpts().CPlusPlus)) {
if (DirectDeclParser)
(this->*DirectDeclParser)(D);
return;
@@ -3859,7 +3591,7 @@
// Complain about rvalue references in C++03, but then go on and build
// the declarator.
if (Kind == tok::ampamp)
- Diag(Loc, getLang().CPlusPlus0x ?
+ Diag(Loc, getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_rvalue_reference :
diag::ext_rvalue_reference);
@@ -3946,7 +3678,7 @@
void Parser::ParseDirectDeclarator(Declarator &D) {
DeclaratorScopeObj DeclScopeObj(*this, D.getCXXScopeSpec());
- if (getLang().CPlusPlus && D.mayHaveIdentifier()) {
+ if (getLangOpts().CPlusPlus && D.mayHaveIdentifier()) {
// ParseDeclaratorInternal might already have parsed the scope.
if (D.getCXXScopeSpec().isEmpty()) {
bool EnteringContext = D.getContext() == Declarator::FileContext ||
@@ -4013,7 +3745,7 @@
goto PastIdentifier;
}
} else if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {
- assert(!getLang().CPlusPlus &&
+ assert(!getLangOpts().CPlusPlus &&
"There's a C++-specific check for tok::identifier above");
assert(Tok.getIdentifierInfo() && "Not an identifier?");
D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
@@ -4047,8 +3779,8 @@
if (D.getContext() == Declarator::MemberContext)
Diag(Tok, diag::err_expected_member_name_or_semi)
<< D.getDeclSpec().getSourceRange();
- else if (getLang().CPlusPlus)
- Diag(Tok, diag::err_expected_unqualified_id) << getLang().CPlusPlus;
+ else if (getLangOpts().CPlusPlus)
+ Diag(Tok, diag::err_expected_unqualified_id) << getLangOpts().CPlusPlus;
else
Diag(Tok, diag::err_expected_ident_lparen);
D.SetIdentifier(0, Tok.getLocation());
@@ -4072,7 +3804,7 @@
// The paren may be part of a C++ direct initializer, eg. "int x(1);".
// In such a case, check if we actually have a function declarator; if it
// is not, the declarator has been fully parsed.
- if (getLang().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) {
+ if (getLangOpts().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) {
// When not in file scope, warn for ambiguous function declarators, just
// in case the author intended it as a variable definition.
bool warnIfAmbiguous = D.getContext() != Declarator::FileContext;
@@ -4152,7 +3884,7 @@
// paren, because we haven't seen the identifier yet.
isGrouping = true;
} else if (Tok.is(tok::r_paren) || // 'int()' is a function.
- (getLang().CPlusPlus && Tok.is(tok::ellipsis)) || // C++ int(...)
+ (getLangOpts().CPlusPlus && Tok.is(tok::ellipsis)) || // C++ int(...)
isDeclarationSpecifier()) { // 'int(int)' is a function.
// This handles C99 6.7.5.3p11: in "typedef int X; void foo(X)", X is
// considered to be a type, not a K&R identifier-list.
@@ -4258,13 +3990,13 @@
else if (RequiresArg)
Diag(Tok, diag::err_argument_required_after_attribute);
- HasProto = ParamInfo.size() || getLang().CPlusPlus;
+ HasProto = ParamInfo.size() || getLangOpts().CPlusPlus;
// If we have the closing ')', eat it.
Tracker.consumeClose();
EndLoc = Tracker.getCloseLocation();
- if (getLang().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
MaybeParseCXX0XAttributes(attrs);
// Parse cv-qualifier-seq[opt].
@@ -4277,7 +4009,7 @@
// Parse ref-qualifier[opt].
if (Tok.is(tok::amp) || Tok.is(tok::ampamp)) {
- Diag(Tok, getLang().CPlusPlus0x ?
+ Diag(Tok, getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_ref_qualifier :
diag::ext_ref_qualifier);
@@ -4295,7 +4027,7 @@
EndLoc = ESpecRange.getEnd();
// Parse trailing-return-type[opt].
- if (getLang().CPlusPlus0x && Tok.is(tok::arrow)) {
+ if (getLangOpts().CPlusPlus0x && Tok.is(tok::arrow)) {
Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
SourceRange Range;
TrailingReturnType = ParseTrailingReturnType(Range).get();
@@ -4335,7 +4067,7 @@
/// Note that identifier-lists are only allowed for normal declarators, not for
/// abstract-declarators.
bool Parser::isFunctionDeclaratorIdentifierList() {
- return !getLang().CPlusPlus
+ return !getLangOpts().CPlusPlus
&& Tok.is(tok::identifier)
&& !TryAltiVecVectorToken()
// K&R identifier lists can't have typedefs as identifiers, per C99
@@ -4437,6 +4169,7 @@
/// parameter-declaration: [C99 6.7.5]
/// declaration-specifiers declarator
/// [C++] declaration-specifiers declarator '=' assignment-expression
+/// [C++11] initializer-clause
/// [GNU] declaration-specifiers declarator attributes
/// declaration-specifiers abstract-declarator[opt]
/// [C++] declaration-specifiers abstract-declarator[opt]
@@ -4460,7 +4193,7 @@
DeclSpec DS(AttrFactory);
// Skip any Microsoft attributes before a param.
- if (getLang().MicrosoftExt && Tok.is(tok::l_square))
+ if (getLangOpts().MicrosoftExt && Tok.is(tok::l_square))
ParseMicrosoftAttributes(DS.getAttributes());
SourceLocation DSStart = Tok.getLocation();
@@ -4548,7 +4281,12 @@
Sema::PotentiallyEvaluatedIfUsed,
Param);
- ExprResult DefArgResult(ParseAssignmentExpression());
+ ExprResult DefArgResult;
+ if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) {
+ Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
+ DefArgResult = ParseBraceInitializer();
+ } else
+ DefArgResult = ParseAssignmentExpression();
if (DefArgResult.isInvalid()) {
Actions.ActOnParamDefaultArgumentError(Param);
SkipUntil(tok::comma, tok::r_paren, true, true);
@@ -4570,7 +4308,7 @@
if (Tok.is(tok::ellipsis)) {
EllipsisLoc = ConsumeToken(); // Consume the ellipsis.
- if (!getLang().CPlusPlus) {
+ if (!getLangOpts().CPlusPlus) {
// We have ellipsis without a preceding ',', which is ill-formed
// in C. Complain and provide the fix.
Diag(EllipsisLoc, diag::err_missing_comma_before_ellipsis)
@@ -4613,7 +4351,7 @@
} else if (Tok.getKind() == tok::numeric_constant &&
GetLookAheadToken(1).is(tok::r_square)) {
// [4] is very common. Parse the numeric constant expression.
- ExprResult ExprRes(Actions.ActOnNumericConstant(Tok));
+ ExprResult ExprRes(Actions.ActOnNumericConstant(Tok, getCurScope()));
ConsumeToken();
T.consumeClose();
@@ -4668,7 +4406,7 @@
// Parse the constant-expression or assignment-expression now (depending
// on dialect).
- if (getLang().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
NumElements = ParseConstantExpression();
} else {
EnterExpressionEvaluationContext Unevaluated(Actions,
Modified: cfe/branches/tooling/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseDeclCXX.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseDeclCXX.cpp Mon Mar 19 14:02:20 2012
@@ -150,7 +150,7 @@
// If we're still good, complain about inline namespaces in non-C++0x now.
if (InlineLoc.isValid())
- Diag(InlineLoc, getLang().CPlusPlus0x ?
+ Diag(InlineLoc, getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_inline_namespace : diag::ext_inline_namespace);
// Enter a scope for the namespace.
@@ -490,7 +490,7 @@
// Where can GNU attributes appear?
ConsumeToken();
- Diag(Tok.getLocation(), getLang().CPlusPlus0x ?
+ Diag(Tok.getLocation(), getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_alias_declaration :
diag::ext_alias_declaration);
@@ -593,7 +593,7 @@
assert((Tok.is(tok::kw_static_assert) || Tok.is(tok::kw__Static_assert)) &&
"Not a static_assert declaration");
- if (Tok.is(tok::kw__Static_assert) && !getLang().C11)
+ if (Tok.is(tok::kw__Static_assert) && !getLangOpts().C11)
Diag(Tok, diag::ext_c11_static_assert);
if (Tok.is(tok::kw_static_assert))
Diag(Tok, diag::warn_cxx98_compat_static_assert);
@@ -903,7 +903,7 @@
/// 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. If SuppressDeclarations is true, we do know.
+/// cannot start a definition.
///
/// class-specifier: [C++ class]
/// class-head '{' member-specification[opt] '}'
@@ -944,8 +944,7 @@
SourceLocation StartLoc, DeclSpec &DS,
const ParsedTemplateInfo &TemplateInfo,
AccessSpecifier AS,
- bool EnteringContext,
- bool SuppressDeclarations){
+ bool EnteringContext, DeclSpecContext DSC) {
DeclSpec::TST TagType;
if (TagTokKind == tok::kw_struct)
TagType = DeclSpec::TST_struct;
@@ -1020,7 +1019,7 @@
// Parse the (optional) nested-name-specifier.
CXXScopeSpec &SS = DS.getTypeSpecScope();
- if (getLang().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
// "FOO : BAR" is not a potential typo for "FOO::BAR".
ColonProtectionRAIIObject X(*this);
@@ -1041,7 +1040,7 @@
Name = Tok.getIdentifierInfo();
NameLoc = ConsumeToken();
- if (Tok.is(tok::less) && getLang().CPlusPlus) {
+ if (Tok.is(tok::less) && getLangOpts().CPlusPlus) {
// The name was supposed to refer to a template, but didn't.
// Eat the template argument list and try to continue parsing this as
// a class (or template thereof).
@@ -1115,23 +1114,29 @@
if (SuppressingAccessChecks)
Actions.ActOnStopSuppressingAccessChecks();
- // There are four options here. If we have 'struct foo;', then this
- // is either a forward declaration or a friend declaration, which
- // have to be treated differently. If we have 'struct foo {...',
- // 'struct foo :...' or 'struct foo final[opt]' then this is a
- // definition. Otherwise we have something like 'struct foo xyz', a reference.
- // However, in some contexts, things look like declarations but are just
- // references, e.g.
- // new struct s;
+ // There are four options here.
+ // - If we are in a trailing return type, this is always just a reference,
+ // and we must not try to parse a definition. For instance,
+ // [] () -> struct S { };
+ // does not define a type.
+ // - If we have 'struct foo {...', 'struct foo :...',
+ // 'struct foo final :' or 'struct foo final {', then this is a definition.
+ // - If we have 'struct foo;', then this is either a forward declaration
+ // or a friend declaration, which have to be treated differently.
+ // - Otherwise we have something like 'struct foo xyz', a reference.
+ // However, in type-specifier-seq's, things look like declarations but are
+ // just references, e.g.
+ // new struct s;
// or
- // &T::operator struct s;
- // For these, SuppressDeclarations is true.
+ // &T::operator struct s;
+ // For these, DSC is DSC_type_specifier.
Sema::TagUseKind TUK;
- if (SuppressDeclarations)
+ if (DSC == DSC_trailing)
TUK = Sema::TUK_Reference;
- else if (Tok.is(tok::l_brace) ||
- (getLang().CPlusPlus && Tok.is(tok::colon)) ||
- isCXX0XFinalKeyword()) {
+ else if (Tok.is(tok::l_brace) ||
+ (getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
+ (isCXX0XFinalKeyword() &&
+ (NextToken().is(tok::l_brace) || NextToken().is(tok::colon)))) {
if (DS.isFriendSpecified()) {
// C++ [class.friend]p2:
// A class shall not be defined in a friend declaration.
@@ -1146,7 +1151,7 @@
// Okay, this is a class definition.
TUK = Sema::TUK_Definition;
}
- } else if (Tok.is(tok::semi))
+ } else if (Tok.is(tok::semi) && DSC != DSC_type_specifier)
TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
else
TUK = Sema::TUK_Reference;
@@ -1313,9 +1318,9 @@
// If there is a body, parse it and inform the actions module.
if (TUK == Sema::TUK_Definition) {
assert(Tok.is(tok::l_brace) ||
- (getLang().CPlusPlus && Tok.is(tok::colon)) ||
+ (getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
isCXX0XFinalKeyword());
- if (getLang().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempResult.get());
else
ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get());
@@ -1397,7 +1402,7 @@
case tok::r_brace: // struct bar { struct foo {...} }
// Missing ';' at end of struct is accepted as an extension in C mode.
- if (!getLang().CPlusPlus)
+ if (!getLangOpts().CPlusPlus)
ExpectedSemi = false;
break;
}
@@ -1576,7 +1581,7 @@
/// override
/// final
VirtSpecifiers::Specifier Parser::isCXX0XVirtSpecifier(const Token &Tok) const {
- if (!getLang().CPlusPlus)
+ if (!getLangOpts().CPlusPlus)
return VirtSpecifiers::VS_None;
if (Tok.is(tok::identifier)) {
@@ -1617,7 +1622,7 @@
<< PrevSpec
<< FixItHint::CreateRemoval(Tok.getLocation());
- Diag(Tok.getLocation(), getLang().CPlusPlus0x ?
+ Diag(Tok.getLocation(), getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_override_control_keyword :
diag::ext_override_control_keyword)
<< VirtSpecifiers::getSpecifierName(Specifier);
@@ -1628,7 +1633,7 @@
/// isCXX0XFinalKeyword - Determine whether the next token is a C++0x
/// contextual 'final' keyword.
bool Parser::isCXX0XFinalKeyword() const {
- if (!getLang().CPlusPlus)
+ if (!getLangOpts().CPlusPlus)
return false;
if (!Tok.is(tok::identifier))
@@ -1683,7 +1688,7 @@
const ParsedTemplateInfo &TemplateInfo,
ParsingDeclRAIIObject *TemplateDiags) {
if (Tok.is(tok::at)) {
- if (getLang().ObjC1 && NextToken().isObjCAtKeyword(tok::objc_defs))
+ if (getLangOpts().ObjC1 && NextToken().isObjCAtKeyword(tok::objc_defs))
Diag(Tok, diag::err_at_defs_cxx);
else
Diag(Tok, diag::err_at_in_class);
@@ -1842,7 +1847,7 @@
// MSVC permits pure specifier on inline functions declared at class scope.
// Hence check for =0 before checking for function definition.
- if (getLang().MicrosoftExt && Tok.is(tok::equal) &&
+ if (getLangOpts().MicrosoftExt && Tok.is(tok::equal) &&
DeclaratorInfo.isFunctionDeclarator() &&
NextToken().is(tok::numeric_constant)) {
EqualLoc = ConsumeToken();
@@ -1859,7 +1864,7 @@
// In C++11, a non-function declarator followed by an open brace is a
// braced-init-list for an in-class member initialization, not an
// erroneous function definition.
- if (Tok.is(tok::l_brace) && !getLang().CPlusPlus0x) {
+ if (Tok.is(tok::l_brace) && !getLangOpts().CPlusPlus0x) {
DefinitionKind = FDK_Definition;
} else if (DeclaratorInfo.isFunctionDeclarator()) {
if (Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) {
@@ -2006,7 +2011,7 @@
// Handle the initializer.
if (HasDeferredInitializer) {
// The initializer was deferred; parse it and cache the tokens.
- Diag(Tok, getLang().CPlusPlus0x ?
+ Diag(Tok, getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_nonstatic_member_init :
diag::ext_nonstatic_member_init);
@@ -2212,11 +2217,11 @@
SourceLocation FinalLoc;
// Parse the optional 'final' keyword.
- if (getLang().CPlusPlus && Tok.is(tok::identifier)) {
+ if (getLangOpts().CPlusPlus && Tok.is(tok::identifier)) {
assert(isCXX0XFinalKeyword() && "not a class definition");
FinalLoc = ConsumeToken();
- Diag(FinalLoc, getLang().CPlusPlus0x ?
+ Diag(FinalLoc, getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_override_control_keyword :
diag::ext_override_control_keyword) << "final";
}
@@ -2256,7 +2261,7 @@
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
// Each iteration of this loop reads one member-declaration.
- if (getLang().MicrosoftExt && (Tok.is(tok::kw___if_exists) ||
+ if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) ||
Tok.is(tok::kw___if_not_exists))) {
ParseMicrosoftIfExistsClassDeclaration((DeclSpec::TST)TagType, CurAS);
continue;
@@ -2483,7 +2488,7 @@
// Parse the '('.
- if (getLang().CPlusPlus0x && Tok.is(tok::l_brace)) {
+ if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) {
Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
ExprResult InitList = ParseBraceInitializer();
@@ -2522,7 +2527,7 @@
EllipsisLoc);
}
- Diag(Tok, getLang().CPlusPlus0x ? diag::err_expected_lparen_or_lbrace
+ Diag(Tok, getLangOpts().CPlusPlus0x ? diag::err_expected_lparen_or_lbrace
: diag::err_expected_lparen);
return true;
}
@@ -2630,7 +2635,7 @@
// can throw anything".
if (Tok.is(tok::ellipsis)) {
SourceLocation EllipsisLoc = ConsumeToken();
- if (!getLang().MicrosoftExt)
+ if (!getLangOpts().MicrosoftExt)
Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
T.consumeClose();
SpecificationRange.setEnd(T.getCloseLocation());
@@ -2675,14 +2680,7 @@
ConsumeToken();
- // FIXME: Need to suppress declarations when parsing this typename.
- // Otherwise in this function definition:
- //
- // auto f() -> struct X {}
- //
- // struct X is parsed as class definition because of the trailing
- // brace.
- return ParseTypeName(&Range);
+ return ParseTypeName(&Range, Declarator::TrailingReturnContext);
}
/// \brief We have just started parsing the definition of a new class,
Modified: cfe/branches/tooling/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseExpr.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseExpr.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseExpr.cpp Mon Mar 19 14:02:20 2012
@@ -268,7 +268,7 @@
Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
prec::Level NextTokPrec = getBinOpPrecedence(Tok.getKind(),
GreaterThanIsOperator,
- getLang().CPlusPlus0x);
+ getLangOpts().CPlusPlus0x);
SourceLocation ColonLoc;
while (1) {
@@ -358,10 +358,10 @@
// they only appear on the RHS of assignments later.
ExprResult RHS;
bool RHSIsInitList = false;
- if (getLang().CPlusPlus0x && Tok.is(tok::l_brace)) {
+ if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) {
RHS = ParseBraceInitializer();
RHSIsInitList = true;
- } else if (getLang().CPlusPlus && NextTokPrec <= prec::Conditional)
+ } else if (getLangOpts().CPlusPlus && NextTokPrec <= prec::Conditional)
RHS = ParseAssignmentExpression();
else
RHS = ParseCastExpression(false);
@@ -373,7 +373,7 @@
// operator immediately to the right of the RHS.
prec::Level ThisPrec = NextTokPrec;
NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator,
- getLang().CPlusPlus0x);
+ getLangOpts().CPlusPlus0x);
// Assignment and conditional expressions are right-associative.
bool isRightAssoc = ThisPrec == prec::Conditional ||
@@ -401,7 +401,7 @@
LHS = ExprError();
NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator,
- getLang().CPlusPlus0x);
+ getLangOpts().CPlusPlus0x);
}
assert(NextTokPrec <= ThisPrec && "Recursion didn't work!");
@@ -666,7 +666,7 @@
// If this expression is limited to being a unary-expression, the parent can
// not start a cast expression.
ParenParseOption ParenExprType =
- (isUnaryExpression && !getLang().CPlusPlus)? CompoundLiteral : CastExpr;
+ (isUnaryExpression && !getLangOpts().CPlusPlus)? CompoundLiteral : CastExpr;
ParsedType CastTy;
SourceLocation RParenLoc;
@@ -700,7 +700,7 @@
// constant: integer-constant
// constant: floating-constant
- Res = Actions.ActOnNumericConstant(Tok);
+ Res = Actions.ActOnNumericConstant(Tok, /*UDLScope*/getCurScope());
ConsumeToken();
break;
@@ -728,7 +728,7 @@
// constant: enumeration-constant
// Turn a potentially qualified name into a annot_typename or
// annot_cxxscope if it would be valid. This handles things like x::y, etc.
- if (getLang().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
// Avoid the unnecessary parse-time lookup in the common case
// where the syntax forbids a type.
const Token &Next = NextToken();
@@ -751,7 +751,7 @@
SourceLocation ILoc = ConsumeToken();
// Support 'Class.property' and 'super.property' notation.
- if (getLang().ObjC1 && Tok.is(tok::period) &&
+ if (getLangOpts().ObjC1 && Tok.is(tok::period) &&
(Actions.getTypeName(II, ILoc, getCurScope()) ||
// Allow the base to be 'super' if in an objc-method.
(&II == Ident_super && getCurScope()->isInObjcMethodScope()))) {
@@ -759,7 +759,7 @@
// Allow either an identifier or the keyword 'class' (in C++).
if (Tok.isNot(tok::identifier) &&
- !(getLang().CPlusPlus && Tok.is(tok::kw_class))) {
+ !(getLangOpts().CPlusPlus && Tok.is(tok::kw_class))) {
Diag(Tok, diag::err_expected_property_name);
return ExprError();
}
@@ -775,7 +775,7 @@
// the token sequence is ill-formed. However, if there's a ':' or ']' after
// that identifier, this is probably a message send with a missing open
// bracket. Treat it as such.
- if (getLang().ObjC1 && &II == Ident_super && !InMessageExpression &&
+ if (getLangOpts().ObjC1 && &II == Ident_super && !InMessageExpression &&
getCurScope()->isInObjcMethodScope() &&
((Tok.is(tok::identifier) &&
(NextToken().is(tok::colon) || NextToken().is(tok::r_square))) ||
@@ -790,7 +790,7 @@
// send that's missing the opening '['. Recovery
// appropriately. Also take this path if we're performing code
// completion after an Objective-C class name.
- if (getLang().ObjC1 &&
+ if (getLangOpts().ObjC1 &&
((Tok.is(tok::identifier) && !InMessageExpression) ||
Tok.is(tok::code_completion))) {
const Token& Next = NextToken();
@@ -841,7 +841,7 @@
case tok::wide_char_constant:
case tok::utf16_char_constant:
case tok::utf32_char_constant:
- Res = Actions.ActOnCharacterConstant(Tok);
+ Res = Actions.ActOnCharacterConstant(Tok, /*UDLScope*/getCurScope());
ConsumeToken();
break;
case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2]
@@ -875,7 +875,7 @@
// ++ cast-expression
// -- cast-expression
SourceLocation SavedLoc = ConsumeToken();
- Res = ParseCastExpression(!getLang().CPlusPlus);
+ Res = ParseCastExpression(!getLangOpts().CPlusPlus);
if (!Res.isInvalid())
Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get());
return move(Res);
@@ -996,7 +996,7 @@
case tok::kw_typename:
case tok::kw_typeof:
case tok::kw___vector: {
- if (!getLang().CPlusPlus) {
+ if (!getLangOpts().CPlusPlus) {
Diag(Tok, diag::err_expected_expression);
return ExprError();
}
@@ -1014,7 +1014,7 @@
DeclSpec DS(AttrFactory);
ParseCXXSimpleTypeSpecifier(DS);
if (Tok.isNot(tok::l_paren) &&
- (!getLang().CPlusPlus0x || Tok.isNot(tok::l_brace)))
+ (!getLangOpts().CPlusPlus0x || Tok.isNot(tok::l_brace)))
return ExprError(Diag(Tok, diag::err_expected_lparen_after_type)
<< DS.getSourceRange());
@@ -1198,8 +1198,8 @@
return ExprError();
}
case tok::l_square:
- if (getLang().CPlusPlus0x) {
- if (getLang().ObjC1) {
+ if (getLangOpts().CPlusPlus0x) {
+ if (getLangOpts().ObjC1) {
// C++11 lambda expressions and Objective-C message sends both start with a
// square bracket. There are three possibilities here:
// we have a valid lambda expression, we have an invalid lambda
@@ -1213,7 +1213,7 @@
Res = ParseLambdaExpression();
break;
}
- if (getLang().ObjC1) {
+ if (getLangOpts().ObjC1) {
Res = ParseObjCMessageExpression();
break;
}
@@ -1265,7 +1265,7 @@
// If we see identifier: after an expression, and we're not already in a
// message send, then this is probably a message send with a missing
// opening bracket '['.
- if (getLang().ObjC1 && !InMessageExpression &&
+ if (getLangOpts().ObjC1 && !InMessageExpression &&
(NextToken().is(tok::colon) || NextToken().is(tok::r_square))) {
LHS = ParseObjCMessageExpressionBody(SourceLocation(), SourceLocation(),
ParsedType(), LHS.get());
@@ -1283,7 +1283,7 @@
// actually another message send. In this case, do some look-ahead to see
// if the contents of the square brackets are obviously not a valid
// expression and recover by pretending there is no suffix.
- if (getLang().ObjC1 && Tok.isAtStartOfLine() &&
+ if (getLangOpts().ObjC1 && Tok.isAtStartOfLine() &&
isSimpleObjCMessageExpression())
return move(LHS);
@@ -1291,7 +1291,7 @@
T.consumeOpen();
Loc = T.getOpenLocation();
ExprResult Idx;
- if (getLang().CPlusPlus0x && Tok.is(tok::l_brace)) {
+ if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) {
Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
Idx = ParseBraceInitializer();
} else
@@ -1411,7 +1411,7 @@
CXXScopeSpec SS;
ParsedType ObjectType;
bool MayBePseudoDestructor = false;
- if (getLang().CPlusPlus && !LHS.isInvalid()) {
+ if (getLangOpts().CPlusPlus && !LHS.isInvalid()) {
LHS = Actions.ActOnStartCXXMemberReference(getCurScope(), LHS.take(),
OpLoc, OpKind, ObjectType,
MayBePseudoDestructor);
@@ -1449,7 +1449,7 @@
// FIXME: Add support for explicit call of template constructor.
SourceLocation TemplateKWLoc;
UnqualifiedId Name;
- if (getLang().ObjC2 && OpKind == tok::period && Tok.is(tok::kw_class)) {
+ if (getLangOpts().ObjC2 && OpKind == tok::period && Tok.is(tok::kw_class)) {
// Objective-C++:
// After a '.' in a member access expression, treat the keyword
// 'class' as if it were an identifier.
@@ -1464,7 +1464,7 @@
/*EnteringContext=*/false,
/*AllowDestructorName=*/true,
/*AllowConstructorName=*/
- getLang().MicrosoftExt,
+ getLangOpts().MicrosoftExt,
ObjectType, TemplateKWLoc, Name))
LHS = ExprError();
@@ -1524,7 +1524,7 @@
// If the operand doesn't start with an '(', it must be an expression.
if (Tok.isNot(tok::l_paren)) {
isCastExpr = false;
- if (OpTok.is(tok::kw_typeof) && !getLang().CPlusPlus) {
+ if (OpTok.is(tok::kw_typeof) && !getLangOpts().CPlusPlus) {
Diag(Tok,diag::err_expected_lparen_after_id) << OpTok.getIdentifierInfo();
return ExprError();
}
@@ -1549,7 +1549,7 @@
return ExprEmpty();
}
- if (getLang().CPlusPlus || OpTok.isNot(tok::kw_typeof)) {
+ if (getLangOpts().CPlusPlus || OpTok.isNot(tok::kw_typeof)) {
// GNU typeof in C requires the expression to be parenthesized. Not so for
// sizeof/alignof or in C++. Therefore, the parenthesized expression is
// the start of a unary-expression, but doesn't include any postfix
@@ -1898,12 +1898,12 @@
}
// Diagnose use of bridge casts in non-arc mode.
- bool BridgeCast = (getLang().ObjC2 &&
+ bool BridgeCast = (getLangOpts().ObjC2 &&
(Tok.is(tok::kw___bridge) ||
Tok.is(tok::kw___bridge_transfer) ||
Tok.is(tok::kw___bridge_retained) ||
Tok.is(tok::kw___bridge_retain)));
- if (BridgeCast && !getLang().ObjCAutoRefCount) {
+ if (BridgeCast && !getLangOpts().ObjCAutoRefCount) {
StringRef BridgeCastName = Tok.getName();
SourceLocation BridgeKeywordLoc = ConsumeToken();
if (!PP.getSourceManager().isInSystemHeader(BridgeKeywordLoc))
@@ -1984,7 +1984,7 @@
// this is probably an Objective-C message send where the leading '[' is
// missing. Recover as if that were the case.
if (!DeclaratorInfo.isInvalidType() && Tok.is(tok::identifier) &&
- !InMessageExpression && getLang().ObjC1 &&
+ !InMessageExpression && getLangOpts().ObjC1 &&
(NextToken().is(tok::colon) || NextToken().is(tok::r_square))) {
TypeResult Ty;
{
@@ -2027,7 +2027,7 @@
}
// Reject the cast of super idiom in ObjC.
- if (Tok.is(tok::identifier) && getLang().ObjC1 &&
+ if (Tok.is(tok::identifier) && getLangOpts().ObjC1 &&
Tok.getIdentifierInfo() == Ident_super &&
getCurScope()->isInObjcMethodScope() &&
GetLookAheadToken(1).isNot(tok::period)) {
@@ -2098,7 +2098,7 @@
SourceLocation LParenLoc,
SourceLocation RParenLoc) {
assert(Tok.is(tok::l_brace) && "Not a compound literal!");
- if (!getLang().C99) // Compound literals don't exist in C90.
+ if (!getLangOpts().C99) // Compound literals don't exist in C90.
Diag(LParenLoc, diag::ext_c99_compound_literal);
ExprResult Result = ParseInitializer();
if (!Result.isInvalid() && Ty)
@@ -2120,18 +2120,13 @@
SmallVector<Token, 4> StringToks;
do {
- if (!AllowUserDefinedLiteral && Tok.hasUDSuffix()) {
- Diag(Tok, diag::err_invalid_string_udl);
- do ConsumeStringToken(); while (isTokenStringLiteral());
- return ExprError();
- }
-
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());
+ return Actions.ActOnStringLiteral(&StringToks[0], StringToks.size(),
+ AllowUserDefinedLiteral ? getCurScope() : 0);
}
/// ParseGenericSelectionExpression - Parse a C11 generic-selection
@@ -2149,7 +2144,7 @@
assert(Tok.is(tok::kw__Generic) && "_Generic keyword expected");
SourceLocation KeyLoc = ConsumeToken();
- if (!getLang().C11)
+ if (!getLangOpts().C11)
Diag(KeyLoc, diag::ext_c11_generic_selection);
BalancedDelimiterTracker T(*this, tok::l_paren);
@@ -2267,7 +2262,7 @@
}
ExprResult Expr;
- if (getLang().CPlusPlus0x && Tok.is(tok::l_brace)) {
+ if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) {
Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
Expr = ParseBraceInitializer();
} else
Modified: cfe/branches/tooling/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseExprCXX.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseExprCXX.cpp Mon Mar 19 14:02:20 2012
@@ -15,6 +15,7 @@
#include "clang/Parse/Parser.h"
#include "RAIIObjectsForParser.h"
#include "clang/Basic/PrettyStackTrace.h"
+#include "clang/Lex/LiteralSupport.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Scope.h"
#include "clang/Sema/ParsedTemplate.h"
@@ -137,7 +138,7 @@
bool EnteringContext,
bool *MayBePseudoDestructor,
bool IsTypename) {
- assert(getLang().CPlusPlus &&
+ assert(getLangOpts().CPlusPlus &&
"Call sites of this function should be guarded by checking for C++");
if (Tok.is(tok::annot_cxxscope)) {
@@ -415,7 +416,7 @@
// parse correctly as a template, so suggest the keyword 'template'
// before 'getAs' and treat this as a dependent template name.
unsigned DiagID = diag::err_missing_dependent_template_keyword;
- if (getLang().MicrosoftExt)
+ if (getLangOpts().MicrosoftExt)
DiagID = diag::warn_missing_dependent_template_keyword;
Diag(Tok.getLocation(), DiagID)
@@ -577,7 +578,7 @@
///
/// If we are not looking at a lambda expression, returns ExprError().
ExprResult Parser::TryParseLambdaExpression() {
- assert(getLang().CPlusPlus0x
+ assert(getLangOpts().CPlusPlus0x
&& Tok.is(tok::l_square)
&& "Not at the start of a possible lambda expression.");
@@ -656,7 +657,7 @@
if (Tok.is(tok::code_completion)) {
// If we're in Objective-C++ and we have a bare '[', then this is more
// likely to be a message receiver.
- if (getLang().ObjC1 && first)
+ if (getLangOpts().ObjC1 && first)
Actions.CodeCompleteObjCMessageReceiver(getCurScope());
else
Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro,
@@ -1224,7 +1225,7 @@
ParsedType TypeRep = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get();
assert((Tok.is(tok::l_paren) ||
- (getLang().CPlusPlus0x && Tok.is(tok::l_brace)))
+ (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)))
&& "Expected '(' or '{'!");
if (Tok.is(tok::l_brace)) {
@@ -1349,7 +1350,7 @@
ConsumeToken();
ExprResult InitExpr = ExprError();
- if (getLang().CPlusPlus0x && Tok.is(tok::l_brace)) {
+ if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace)) {
Diag(Tok.getLocation(),
diag::warn_cxx98_compat_generalized_initializer_lists);
InitExpr = ParseBraceInitializer();
@@ -1466,7 +1467,7 @@
// is a specific typedef and 'itf<proto1,proto2>' where 'itf' is an
// Objective-C interface. If we don't have Objective-C or a '<', this is
// just a normal reference to a typedef name.
- if (Tok.is(tok::less) && getLang().ObjC1)
+ if (Tok.is(tok::less) && getLangOpts().ObjC1)
ParseObjCProtocolQualifiers(DS);
DS.Finish(Diags, PP);
@@ -1550,22 +1551,7 @@
/// type-specifier type-specifier-seq[opt]
///
bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) {
- DS.SetRangeStart(Tok.getLocation());
- const char *PrevSpec = 0;
- unsigned DiagID;
- bool isInvalid = 0;
-
- // Parse one or more of the type specifiers.
- if (!ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
- ParsedTemplateInfo(), /*SuppressDeclarations*/true)) {
- Diag(Tok, diag::err_expected_type);
- return true;
- }
-
- while (ParseOptionalTypeSpecifier(DS, isInvalid, PrevSpec, DiagID,
- ParsedTemplateInfo(), /*SuppressDeclarations*/true))
- {}
-
+ ParseSpecifierQualifierList(DS, AS_none, DSC_type_specifier);
DS.Finish(Diags, PP);
return false;
}
@@ -1903,24 +1889,68 @@
// literal-operator-id: [C++0x 13.5.8]
// operator "" identifier
- if (getLang().CPlusPlus0x && Tok.is(tok::string_literal)) {
+ if (getLangOpts().CPlusPlus0x && isTokenStringLiteral()) {
Diag(Tok.getLocation(), diag::warn_cxx98_compat_literal_operator);
- // FIXME: Add a FixIt to insert a space before the suffix, and recover.
- if (Tok.hasUDSuffix()) {
- Diag(Tok.getLocation(), diag::err_literal_operator_missing_space);
- return true;
+
+ SourceLocation DiagLoc;
+ unsigned DiagId = 0;
+
+ // We're past translation phase 6, so perform string literal concatenation
+ // before checking for "".
+ llvm::SmallVector<Token, 4> Toks;
+ llvm::SmallVector<SourceLocation, 4> TokLocs;
+ while (isTokenStringLiteral()) {
+ if (!Tok.is(tok::string_literal) && !DiagId) {
+ DiagLoc = Tok.getLocation();
+ DiagId = diag::err_literal_operator_string_prefix;
+ }
+ Toks.push_back(Tok);
+ TokLocs.push_back(ConsumeStringToken());
}
- if (Tok.getLength() != 2)
- Diag(Tok.getLocation(), diag::err_literal_operator_string_not_empty);
- ConsumeStringToken();
- if (Tok.isNot(tok::identifier)) {
+ StringLiteralParser Literal(Toks.data(), Toks.size(), PP);
+ if (Literal.hadError)
+ return true;
+
+ // Grab the literal operator's suffix, which will be either the next token
+ // or a ud-suffix from the string literal.
+ IdentifierInfo *II = 0;
+ SourceLocation SuffixLoc;
+ if (!Literal.getUDSuffix().empty()) {
+ II = &PP.getIdentifierTable().get(Literal.getUDSuffix());
+ SuffixLoc =
+ Lexer::AdvanceToTokenCharacter(TokLocs[Literal.getUDSuffixToken()],
+ Literal.getUDSuffixOffset(),
+ PP.getSourceManager(), getLangOpts());
+ // This form is not permitted by the standard (yet).
+ DiagLoc = SuffixLoc;
+ DiagId = diag::err_literal_operator_missing_space;
+ } else if (Tok.is(tok::identifier)) {
+ II = Tok.getIdentifierInfo();
+ SuffixLoc = ConsumeToken();
+ TokLocs.push_back(SuffixLoc);
+ } else {
Diag(Tok.getLocation(), diag::err_expected_ident);
return true;
}
- IdentifierInfo *II = Tok.getIdentifierInfo();
- Result.setLiteralOperatorId(II, KeywordLoc, ConsumeToken());
+ // The string literal must be empty.
+ if (!Literal.GetString().empty() || Literal.Pascal) {
+ DiagLoc = TokLocs.front();
+ DiagId = diag::err_literal_operator_string_not_empty;
+ }
+
+ if (DiagId) {
+ // This isn't a valid literal-operator-id, but we think we know
+ // what the user meant. Tell them what they should have written.
+ llvm::SmallString<32> Str;
+ Str += "\"\" ";
+ Str += II->getName();
+ Diag(DiagLoc, DiagId) << FixItHint::CreateReplacement(
+ SourceRange(TokLocs.front(), TokLocs.back()), Str);
+ }
+
+ Result.setLiteralOperatorId(II, KeywordLoc, SuffixLoc);
return false;
}
@@ -1996,7 +2026,7 @@
// Handle 'A::template B'. This is for template-ids which have not
// already been annotated by ParseOptionalCXXScopeSpecifier().
bool TemplateSpecified = false;
- if (getLang().CPlusPlus && Tok.is(tok::kw_template) &&
+ if (getLangOpts().CPlusPlus && Tok.is(tok::kw_template) &&
(ObjectType || SS.isSet())) {
TemplateSpecified = true;
TemplateKWLoc = ConsumeToken();
@@ -2010,7 +2040,7 @@
IdentifierInfo *Id = Tok.getIdentifierInfo();
SourceLocation IdLoc = ConsumeToken();
- if (!getLang().CPlusPlus) {
+ if (!getLangOpts().CPlusPlus) {
// If we're not in C++, only identifiers matter. Record the
// identifier and return.
Result.setIdentifier(Id, IdLoc);
@@ -2107,7 +2137,7 @@
return false;
}
- if (getLang().CPlusPlus &&
+ if (getLangOpts().CPlusPlus &&
(AllowDestructorName || SS.isSet()) && Tok.is(tok::tilde)) {
// C++ [expr.unary.op]p10:
// There is an ambiguity in the unary-expression ~X(), where X is a
@@ -2158,7 +2188,7 @@
}
Diag(Tok, diag::err_expected_unqualified_id)
- << getLang().CPlusPlus;
+ << getLangOpts().CPlusPlus;
return true;
}
@@ -2288,7 +2318,7 @@
Initializer = Actions.ActOnParenListExpr(ConstructorLParen,
ConstructorRParen,
move_arg(ConstructorArgs));
- } else if (Tok.is(tok::l_brace) && getLang().CPlusPlus0x) {
+ } else if (Tok.is(tok::l_brace) && getLangOpts().CPlusPlus0x) {
Diag(Tok.getLocation(),
diag::warn_cxx98_compat_generalized_initializer_lists);
Initializer = ParseBraceInitializer();
@@ -2679,7 +2709,7 @@
Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType,
ParsedType &CastTy,
BalancedDelimiterTracker &Tracker) {
- assert(getLang().CPlusPlus && "Should only be called for C++!");
+ assert(getLangOpts().CPlusPlus && "Should only be called for C++!");
assert(ExprType == CastExpr && "Compound literals are not ambiguous!");
assert(isTypeIdInParens() && "Not a type-id!");
Modified: cfe/branches/tooling/lib/Parse/ParseInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseInit.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseInit.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseInit.cpp Mon Mar 19 14:02:20 2012
@@ -33,7 +33,7 @@
return true;
case tok::l_square: { // designator: array-designator
- if (!PP.getLangOptions().CPlusPlus0x)
+ if (!PP.getLangOpts().CPlusPlus0x)
return true;
// C++11 lambda expressions and C99 designators can be ambiguous all the
@@ -223,7 +223,7 @@
// send) or send to 'super', parse this as a message send
// expression. We handle C++ and C separately, since C++ requires
// much more complicated parsing.
- if (getLang().ObjC1 && getLang().CPlusPlus) {
+ if (getLangOpts().ObjC1 && getLangOpts().CPlusPlus) {
// Send to 'super'.
if (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super &&
NextToken().isNot(tok::period) &&
@@ -258,7 +258,7 @@
// adopt the expression for further analysis below.
// FIXME: potentially-potentially evaluated expression above?
Idx = ExprResult(static_cast<Expr*>(TypeOrExpr));
- } else if (getLang().ObjC1 && Tok.is(tok::identifier)) {
+ } else if (getLangOpts().ObjC1 && Tok.is(tok::identifier)) {
IdentifierInfo *II = Tok.getIdentifierInfo();
SourceLocation IILoc = Tok.getLocation();
ParsedType ReceiverType;
@@ -316,7 +316,7 @@
// tokens are '...' or ']' or an objc message send. If this is an objc
// message send, handle it now. An objc-message send is the start of
// an assignment-expression production.
- if (getLang().ObjC1 && Tok.isNot(tok::ellipsis) &&
+ if (getLangOpts().ObjC1 && Tok.isNot(tok::ellipsis) &&
Tok.isNot(tok::r_square)) {
CheckArrayDesignatorSyntax(*this, Tok.getLocation(), Desig);
return ParseAssignmentExprWithObjCMessageExprStart(StartLoc,
@@ -404,7 +404,7 @@
if (Tok.is(tok::r_brace)) {
// Empty initializers are a C++ feature and a GNU extension to C.
- if (!getLang().CPlusPlus)
+ if (!getLangOpts().CPlusPlus)
Diag(LBraceLoc, diag::ext_gnu_empty_initializer);
// Match the '}'.
return Actions.ActOnInitList(LBraceLoc, MultiExprArg(Actions),
@@ -415,7 +415,7 @@
while (1) {
// Handle Microsoft __if_exists/if_not_exists if necessary.
- if (getLang().MicrosoftExt && (Tok.is(tok::kw___if_exists) ||
+ if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) ||
Tok.is(tok::kw___if_not_exists))) {
if (ParseMicrosoftIfExistsBraceInitializer(InitExprs, InitExprsOk)) {
if (Tok.isNot(tok::comma)) break;
Modified: cfe/branches/tooling/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseObjc.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseObjc.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseObjc.cpp Mon Mar 19 14:02:20 2012
@@ -65,7 +65,7 @@
SingleDecl = ParseObjCPropertyDynamic(AtLoc);
break;
case tok::objc___experimental_modules_import:
- if (getLang().Modules)
+ if (getLangOpts().Modules)
return ParseModuleImport(AtLoc);
// Fall through
@@ -203,7 +203,7 @@
categoryId = Tok.getIdentifierInfo();
categoryLoc = ConsumeToken();
}
- else if (!getLang().ObjC2) {
+ else if (!getLangOpts().ObjC2) {
Diag(Tok, diag::err_expected_ident); // missing category name.
return 0;
}
@@ -477,7 +477,7 @@
break;
case tok::objc_property:
- if (!getLang().ObjC2)
+ if (!getLangOpts().ObjC2)
Diag(AtLoc, diag::err_objc_properties_require_objc2);
ObjCDeclSpec OCDS;
@@ -778,7 +778,7 @@
// 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) &&
+ return (getLangOpts().ObjC2 && Tok.is(tok::identifier) &&
Tok.getIdentifierInfo() == ObjCTypeQuals[objc_in]);
}
@@ -981,7 +981,7 @@
// If attributes exist before the method, parse them.
ParsedAttributes methodAttrs(AttrFactory);
- if (getLang().ObjC2)
+ if (getLangOpts().ObjC2)
MaybeParseGNUAttributes(methodAttrs);
if (Tok.is(tok::code_completion)) {
@@ -1007,7 +1007,7 @@
SmallVector<DeclaratorChunk::ParamInfo, 8> CParamInfo;
if (Tok.isNot(tok::colon)) {
// If attributes exist after the method, parse them.
- if (getLang().ObjC2)
+ if (getLangOpts().ObjC2)
MaybeParseGNUAttributes(methodAttrs);
Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
@@ -1050,7 +1050,7 @@
// If attributes exist before the argument name, parse them.
// Regardless, collect all the attributes we've parsed so far.
ArgInfo.ArgAttrs = 0;
- if (getLang().ObjC2) {
+ if (getLangOpts().ObjC2) {
MaybeParseGNUAttributes(paramAttrs);
ArgInfo.ArgAttrs = paramAttrs.getList();
}
@@ -1129,7 +1129,7 @@
// FIXME: Add support for optional parameter list...
// If attributes exist after the method, parse them.
- if (getLang().ObjC2)
+ if (getLangOpts().ObjC2)
MaybeParseGNUAttributes(methodAttrs);
if (KeyIdents.size() == 0)
@@ -1205,7 +1205,7 @@
/// in a decl-specifier-seq, starting at the '<'.
bool Parser::ParseObjCProtocolQualifiers(DeclSpec &DS) {
assert(Tok.is(tok::less) && "Protocol qualifiers start with '<'");
- assert(getLang().ObjC1 && "Protocol qualifiers only exist in Objective-C");
+ assert(getLangOpts().ObjC1 && "Protocol qualifiers only exist in Objective-C");
SourceLocation LAngleLoc, EndProtoLoc;
SmallVector<Decl *, 8> ProtocolDecl;
SmallVector<SourceLocation, 8> ProtocolLocs;
@@ -2042,8 +2042,6 @@
case tok::string_literal: // primary-expression: string-literal
case tok::wide_string_literal:
- if (Tok.hasUDSuffix())
- return ExprError(Diag(Tok, diag::err_invalid_string_udl));
return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
case tok::char_constant:
@@ -2177,14 +2175,14 @@
/// This routine will only return true for a subset of valid message-send
/// expressions.
bool Parser::isSimpleObjCMessageExpression() {
- assert(Tok.is(tok::l_square) && getLang().ObjC1 &&
+ assert(Tok.is(tok::l_square) && getLangOpts().ObjC1 &&
"Incorrect start for isSimpleObjCMessageExpression");
return GetLookAheadToken(1).is(tok::identifier) &&
GetLookAheadToken(2).is(tok::identifier);
}
bool Parser::isStartOfObjCClassMessageMissingOpenBracket() {
- if (!getLang().ObjC1 || !NextToken().is(tok::identifier) ||
+ if (!getLangOpts().ObjC1 || !NextToken().is(tok::identifier) ||
InMessageExpression)
return false;
@@ -2233,7 +2231,7 @@
InMessageExpressionRAIIObject InMessage(*this, true);
- if (getLang().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
// We completely separate the C and C++ cases because C++ requires
// more complicated (read: slower) parsing.
@@ -2649,7 +2647,7 @@
// Parse the ellipsis that designates this as a pack expansion.
SourceLocation EllipsisLoc;
- if (Tok.is(tok::ellipsis) && getLang().CPlusPlus)
+ if (Tok.is(tok::ellipsis) && getLangOpts().CPlusPlus)
EllipsisLoc = ConsumeToken();
// We have a valid expression. Collect it in a vector so we can
Modified: cfe/branches/tooling/lib/Parse/ParsePragma.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParsePragma.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParsePragma.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParsePragma.cpp Mon Mar 19 14:02:20 2012
@@ -143,7 +143,7 @@
// In MSVC/gcc, #pragma pack(4) sets the alignment without affecting
// the push/pop stack.
// In Apple gcc, #pragma pack(4) is equivalent to #pragma pack(push, 4)
- if (PP.getLangOptions().ApplePragmaPack)
+ if (PP.getLangOpts().ApplePragmaPack)
Kind = Sema::PPK_Push;
} else if (Tok.is(tok::identifier)) {
const IdentifierInfo *II = Tok.getIdentifierInfo();
@@ -194,7 +194,7 @@
}
}
}
- } else if (PP.getLangOptions().ApplePragmaPack) {
+ } else if (PP.getLangOpts().ApplePragmaPack) {
// In MSVC/gcc, #pragma pack() resets the alignment without affecting
// the push/pop stack.
// In Apple gcc #pragma pack() is equivalent to #pragma pack(pop).
Modified: cfe/branches/tooling/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseStmt.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseStmt.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseStmt.cpp Mon Mar 19 14:02:20 2012
@@ -116,7 +116,7 @@
IdentifierInfo *Name = Tok.getIdentifierInfo();
SourceLocation NameLoc = Tok.getLocation();
- if (getLang().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
CheckForTemplateAndDigraph(Next, ParsedType(),
/*EnteringContext=*/false, *Name, SS);
@@ -207,7 +207,7 @@
}
default: {
- if ((getLang().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) {
+ if ((getLangOpts().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) {
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
DeclGroupPtrTy Decl = ParseDeclaration(Stmts, Declarator::BlockContext,
DeclEnd, attrs);
@@ -399,14 +399,14 @@
ParseScope ExpectScope(this, Scope::DeclScope | Scope::ControlScope);
- if (getLang().Borland) {
+ if (getLangOpts().Borland) {
Ident__exception_info->setIsPoisoned(false);
Ident___exception_info->setIsPoisoned(false);
Ident_GetExceptionInfo->setIsPoisoned(false);
}
ExprResult FilterExpr(ParseExpression());
- if (getLang().Borland) {
+ if (getLangOpts().Borland) {
Ident__exception_info->setIsPoisoned(true);
Ident___exception_info->setIsPoisoned(true);
Ident_GetExceptionInfo->setIsPoisoned(true);
@@ -770,7 +770,7 @@
continue;
}
- if (getLang().MicrosoftExt && (Tok.is(tok::kw___if_exists) ||
+ if (getLangOpts().MicrosoftExt && (Tok.is(tok::kw___if_exists) ||
Tok.is(tok::kw___if_not_exists))) {
ParseMicrosoftIfExistsStatement(Stmts);
continue;
@@ -855,7 +855,7 @@
BalancedDelimiterTracker T(*this, tok::l_paren);
T.consumeOpen();
- if (getLang().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
ParseCXXCondition(ExprResult, DeclResult, Loc, ConvertToBoolean);
else {
ExprResult = ParseExpression();
@@ -904,7 +904,7 @@
return StmtError();
}
- bool C99orCXX = getLang().C99 || getLang().CPlusPlus;
+ bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
// C99 6.8.4p3 - In C99, the if statement is a block. This is not
// the case for C90.
@@ -1038,7 +1038,7 @@
return StmtError();
}
- bool C99orCXX = getLang().C99 || getLang().CPlusPlus;
+ bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
// C99 6.8.4p3 - In C99, the switch statement is a block. This is
// not the case for C90. Start the switch scope.
@@ -1130,7 +1130,7 @@
return StmtError();
}
- bool C99orCXX = getLang().C99 || getLang().CPlusPlus;
+ bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
// C99 6.8.5p5 - In C99, the while statement is a block. This is not
// the case for C90. Start the loop scope.
@@ -1200,7 +1200,7 @@
// C99 6.8.5p5 - In C99, the do statement is a block. This is not
// the case for C90. Start the loop scope.
unsigned ScopeFlags;
- if (getLang().C99)
+ if (getLangOpts().C99)
ScopeFlags = Scope::BreakScope | Scope::ContinueScope | Scope::DeclScope;
else
ScopeFlags = Scope::BreakScope | Scope::ContinueScope;
@@ -1216,7 +1216,7 @@
// which is entered and exited each time through the loop.
//
ParseScope InnerScope(this, Scope::DeclScope,
- (getLang().C99 || getLang().CPlusPlus) &&
+ (getLangOpts().C99 || getLangOpts().CPlusPlus) &&
Tok.isNot(tok::l_brace));
// Read the body statement.
@@ -1287,7 +1287,7 @@
return StmtError();
}
- bool C99orCXXorObjC = getLang().C99 || getLang().CPlusPlus || getLang().ObjC1;
+ bool C99orCXXorObjC = getLangOpts().C99 || getLangOpts().CPlusPlus || getLangOpts().ObjC1;
// C99 6.8.5p5 - In C99, the for statement is a block. This is not
// the case for C90. Start the loop scope.
@@ -1348,7 +1348,7 @@
MaybeParseCXX0XAttributes(attrs);
// In C++0x, "for (T NS:a" might not be a typo for ::
- bool MightBeForRangeStmt = getLang().CPlusPlus;
+ bool MightBeForRangeStmt = getLangOpts().CPlusPlus;
ColonProtectionRAIIObject ColonProtection(*this, MightBeForRangeStmt);
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
@@ -1360,7 +1360,7 @@
FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
if (ForRangeInit.ParsedForRangeDecl()) {
- Diag(ForRangeInit.ColonLoc, getLang().CPlusPlus0x ?
+ Diag(ForRangeInit.ColonLoc, getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_for_range : diag::ext_for_range);
ForRange = true;
@@ -1404,7 +1404,7 @@
return StmtError();
}
Collection = ParseExpression();
- } else if (getLang().CPlusPlus0x && Tok.is(tok::colon) && FirstPart.get()) {
+ } else if (getLangOpts().CPlusPlus0x && Tok.is(tok::colon) && FirstPart.get()) {
// User tried to write the reasonable, but ill-formed, for-range-statement
// for (expr : expr) { ... }
Diag(Tok, diag::err_for_range_expected_decl)
@@ -1431,7 +1431,7 @@
// missing both semicolons.
} else {
ExprResult Second;
- if (getLang().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
ParseCXXCondition(Second, SecondVar, ForLoc, true);
else {
Second = ParseExpression();
@@ -1605,10 +1605,10 @@
return StmtError();
}
- if (Tok.is(tok::l_brace) && getLang().CPlusPlus) {
+ if (Tok.is(tok::l_brace) && getLangOpts().CPlusPlus) {
R = ParseInitializer();
if (R.isUsable())
- Diag(R.get()->getLocStart(), getLang().CPlusPlus0x ?
+ Diag(R.get()->getLocStart(), getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_generalized_initializer_lists :
diag::ext_generalized_initializer_lists)
<< R.get()->getSourceRange();
@@ -1771,7 +1771,7 @@
assert(Tok.is(tok::kw_asm) && "Not an asm stmt");
SourceLocation AsmLoc = ConsumeToken();
- if (getLang().MicrosoftExt && Tok.isNot(tok::l_paren) && !isTypeQualifier()) {
+ if (getLangOpts().MicrosoftExt && Tok.isNot(tok::l_paren) && !isTypeQualifier()) {
msAsm = true;
return ParseMicrosoftAsmStatement(AsmLoc);
}
Modified: cfe/branches/tooling/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseTemplate.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseTemplate.cpp Mon Mar 19 14:02:20 2012
@@ -478,7 +478,7 @@
EllipsisLoc = ConsumeToken();
Diag(EllipsisLoc,
- getLang().CPlusPlus0x
+ getLangOpts().CPlusPlus0x
? diag::warn_cxx98_compat_variadic_templates
: diag::ext_variadic_templates);
}
@@ -553,7 +553,7 @@
EllipsisLoc = ConsumeToken();
Diag(EllipsisLoc,
- getLang().CPlusPlus0x
+ getLangOpts().CPlusPlus0x
? diag::warn_cxx98_compat_variadic_templates
: diag::ext_variadic_templates);
}
@@ -716,7 +716,7 @@
if (NextToken().is(tok::greater) || NextToken().is(tok::greatergreater))
ReplaceStr = "> > ";
- Diag(Tok.getLocation(), getLang().CPlusPlus0x ?
+ Diag(Tok.getLocation(), getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_two_right_angle_brackets :
diag::err_two_right_angle_brackets_need_space)
<< FixItHint::CreateReplacement(SourceRange(Tok.getLocation()),
@@ -776,7 +776,7 @@
SourceLocation TemplateKWLoc,
UnqualifiedId &TemplateName,
bool AllowTypeAnnotation) {
- assert(getLang().CPlusPlus && "Can only annotate template-ids in C++");
+ assert(getLangOpts().CPlusPlus && "Can only annotate template-ids in C++");
assert(Template && Tok.is(tok::less) &&
"Parser isn't at the beginning of a template-id");
Modified: cfe/branches/tooling/lib/Parse/ParseTentative.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseTentative.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseTentative.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseTentative.cpp Mon Mar 19 14:02:20 2012
@@ -149,7 +149,7 @@
else {
ConsumeToken();
- if (getLang().ObjC1 && Tok.is(tok::less))
+ if (getLangOpts().ObjC1 && Tok.is(tok::less))
TryParseProtocolQualifiers();
}
@@ -258,7 +258,7 @@
else {
ConsumeToken();
- if (getLang().ObjC1 && Tok.is(tok::less))
+ if (getLangOpts().ObjC1 && Tok.is(tok::less))
TryParseProtocolQualifiers();
}
assert(Tok.is(tok::l_paren) && "Expected '('");
@@ -276,7 +276,7 @@
if (Tok.is(tok::equal) ||
Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))
TPR = TPResult::True();
- else if (getLang().CPlusPlus0x && Tok.is(tok::l_brace))
+ else if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace))
TPR = TPResult::True();
else
TPR = TPResult::False();
@@ -335,7 +335,7 @@
else {
ConsumeToken();
- if (getLang().ObjC1 && Tok.is(tok::less))
+ if (getLangOpts().ObjC1 && Tok.is(tok::less))
TryParseProtocolQualifiers();
}
@@ -360,7 +360,7 @@
// ',', this is a type-id. Otherwise, it's an expression.
} else if (Context == TypeIdAsTemplateArgument &&
(Tok.is(tok::greater) || Tok.is(tok::comma) ||
- (getLang().CPlusPlus0x && Tok.is(tok::greatergreater)))) {
+ (getLangOpts().CPlusPlus0x && Tok.is(tok::greatergreater)))) {
TPR = TPResult::True();
isAmbiguous = true;
@@ -430,7 +430,7 @@
return false;
// No tentative parsing if we don't need to look for ]]
- if (!CheckClosing && !getLang().ObjC1)
+ if (!CheckClosing && !getLangOpts().ObjC1)
return true;
struct TentativeReverter {
@@ -1005,7 +1005,7 @@
case tok::annot_typename:
case_typename:
// In Objective-C, we might have a protocol-qualified type.
- if (getLang().ObjC1 && NextToken().is(tok::less)) {
+ if (getLangOpts().ObjC1 && NextToken().is(tok::less)) {
// Tentatively parse the
TentativeParsingAction PA(*this);
ConsumeToken(); // The type token
@@ -1022,7 +1022,7 @@
if (isFollowedByParen)
return TPResult::Ambiguous();
- if (getLang().CPlusPlus0x && isFollowedByBrace)
+ if (getLangOpts().CPlusPlus0x && isFollowedByBrace)
return BracedCastResult;
return TPResult::True();
@@ -1053,7 +1053,7 @@
// enum E : int { a = 4 }; // enum
// enum E : int { 4 }; // bit-field
// };
- if (getLang().CPlusPlus0x && NextToken().is(tok::l_brace))
+ if (getLangOpts().CPlusPlus0x && NextToken().is(tok::l_brace))
return BracedCastResult;
if (isStartOfObjCClassMessageMissingOpenBracket())
@@ -1080,7 +1080,7 @@
if (isFollowedByParen)
return TPResult::Ambiguous();
- if (getLang().CPlusPlus0x && isFollowedByBrace)
+ if (getLangOpts().CPlusPlus0x && isFollowedByBrace)
return BracedCastResult;
return TPResult::True();
@@ -1150,7 +1150,7 @@
else {
ConsumeToken();
- if (getLang().ObjC1 && Tok.is(tok::less))
+ if (getLangOpts().ObjC1 && Tok.is(tok::less))
TryParseProtocolQualifiers();
}
Modified: cfe/branches/tooling/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/Parser.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/Parser.cpp (original)
+++ cfe/branches/tooling/lib/Parse/Parser.cpp Mon Mar 19 14:02:20 2012
@@ -25,7 +25,7 @@
IdentifierInfo *Parser::getSEHExceptKeyword() {
// __except is accepted as a (contextual) keyword
- if (!Ident__except && (getLang().MicrosoftExt || getLang().Borland))
+ if (!Ident__except && (getLangOpts().MicrosoftExt || getLangOpts().Borland))
Ident__except = PP.getIdentifierInfo("__except");
return Ident__except;
@@ -70,7 +70,7 @@
FPContractHandler.reset(new PragmaFPContractHandler(actions, *this));
PP.AddPragmaHandler("STDC", FPContractHandler.get());
- if (getLang().OpenCL) {
+ if (getLangOpts().OpenCL) {
OpenCLExtensionHandler.reset(
new PragmaOpenCLExtensionHandler(actions, *this));
PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get());
@@ -388,7 +388,7 @@
PP.RemovePragmaHandler(RedefineExtnameHandler.get());
RedefineExtnameHandler.reset();
- if (getLang().OpenCL) {
+ if (getLangOpts().OpenCL) {
PP.RemovePragmaHandler("OPENCL", OpenCLExtensionHandler.get());
OpenCLExtensionHandler.reset();
PP.RemovePragmaHandler("OPENCL", FPContractHandler.get());
@@ -411,12 +411,12 @@
ConsumeToken();
if (Tok.is(tok::eof) &&
- !getLang().CPlusPlus) // Empty source file is an extension in C
+ !getLangOpts().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) {
+ if (getLangOpts().ObjC1) {
ObjCTypeQuals[objc_in] = &PP.getIdentifierTable().get("in");
ObjCTypeQuals[objc_out] = &PP.getIdentifierTable().get("out");
ObjCTypeQuals[objc_inout] = &PP.getIdentifierTable().get("inout");
@@ -431,7 +431,7 @@
Ident_super = &PP.getIdentifierTable().get("super");
- if (getLang().AltiVec) {
+ if (getLangOpts().AltiVec) {
Ident_vector = &PP.getIdentifierTable().get("vector");
Ident_pixel = &PP.getIdentifierTable().get("pixel");
}
@@ -447,7 +447,7 @@
Ident___exception_code = Ident___exception_info = Ident___abnormal_termination = 0;
Ident_GetExceptionCode = Ident_GetExceptionInfo = Ident_AbnormalTermination = 0;
- if(getLang().Borland) {
+ if(getLangOpts().Borland) {
Ident__exception_info = PP.getIdentifierInfo("_exception_info");
Ident___exception_info = PP.getIdentifierInfo("__exception_info");
Ident_GetExceptionInfo = PP.getIdentifierInfo("GetExceptionInformation");
@@ -475,23 +475,30 @@
bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
DelayedCleanupPoint CleanupRAII(TopLevelDeclCleanupPool);
+ // Skip over the EOF token, flagging end of previous input for incremental
+ // processing
+ if (PP.isIncrementalProcessingEnabled() && Tok.is(tok::eof))
+ ConsumeToken();
+
while (Tok.is(tok::annot_pragma_unused))
HandlePragmaUnused();
Result = DeclGroupPtrTy();
if (Tok.is(tok::eof)) {
// Late template parsing can begin.
- if (getLang().DelayedTemplateParsing)
+ if (getLangOpts().DelayedTemplateParsing)
Actions.SetLateTemplateParser(LateTemplateParserCallback, this);
+ if (!PP.isIncrementalProcessingEnabled())
+ Actions.ActOnEndOfTranslationUnit();
+ //else don't tell Sema that we ended parsing: more input might come.
- Actions.ActOnEndOfTranslationUnit();
return true;
}
ParsedAttributesWithRange attrs(AttrFactory);
MaybeParseCXX0XAttributes(attrs);
MaybeParseMicrosoftAttributes(attrs);
-
+
Result = ParseExternalDeclaration(attrs);
return false;
}
@@ -553,7 +560,7 @@
HandlePragmaPack();
return DeclGroupPtrTy();
case tok::semi:
- Diag(Tok, getLang().CPlusPlus0x ?
+ Diag(Tok, getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_top_level_semi : diag::ext_top_level_semi)
<< FixItHint::CreateRemoval(Tok.getLocation());
@@ -592,7 +599,7 @@
return ParseObjCAtDirectives();
case tok::minus:
case tok::plus:
- if (!getLang().ObjC1) {
+ if (!getLangOpts().ObjC1) {
Diag(Tok, diag::err_expected_external_declaration);
ConsumeToken();
return DeclGroupPtrTy();
@@ -622,7 +629,7 @@
case tok::kw_static:
// Parse (then ignore) 'static' prior to a template instantiation. This is
// a GCC extension that we intentionally do not support.
- if (getLang().CPlusPlus && NextToken().is(tok::kw_template)) {
+ if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_template)) {
Diag(ConsumeToken(), diag::warn_static_inline_explicit_inst_ignored)
<< 0;
SourceLocation DeclEnd;
@@ -632,7 +639,7 @@
goto dont_know;
case tok::kw_inline:
- if (getLang().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
tok::TokenKind NextKind = NextToken().getKind();
// Inline namespaces. Allowed as an extension even in C++03.
@@ -655,11 +662,11 @@
goto dont_know;
case tok::kw_extern:
- if (getLang().CPlusPlus && NextToken().is(tok::kw_template)) {
+ if (getLangOpts().CPlusPlus && NextToken().is(tok::kw_template)) {
// Extern templates
SourceLocation ExternLoc = ConsumeToken();
SourceLocation TemplateLoc = ConsumeToken();
- Diag(ExternLoc, getLang().CPlusPlus0x ?
+ Diag(ExternLoc, getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_extern_template :
diag::ext_extern_template) << SourceRange(ExternLoc, TemplateLoc);
SourceLocation DeclEnd;
@@ -695,7 +702,7 @@
/// declarator, continues a declaration or declaration list.
bool Parser::isDeclarationAfterDeclarator() {
// Check for '= delete' or '= default'
- if (getLang().CPlusPlus && Tok.is(tok::equal)) {
+ if (getLangOpts().CPlusPlus && Tok.is(tok::equal)) {
const Token &KW = NextToken();
if (KW.is(tok::kw_default) || KW.is(tok::kw_delete))
return false;
@@ -706,7 +713,7 @@
Tok.is(tok::semi) || // int X(); -> not a function def
Tok.is(tok::kw_asm) || // int X() __asm__ -> not a function def
Tok.is(tok::kw___attribute) || // int X() __attr__ -> not a function def
- (getLang().CPlusPlus &&
+ (getLangOpts().CPlusPlus &&
Tok.is(tok::l_paren)); // int X(0) -> not a function def [C++]
}
@@ -718,11 +725,11 @@
return true;
// Handle K&R C argument lists: int X(f) int f; {}
- if (!getLang().CPlusPlus &&
+ if (!getLangOpts().CPlusPlus &&
Declarator.getFunctionTypeInfo().isKNRPrototype())
return isDeclarationSpecifier();
- if (getLang().CPlusPlus && Tok.is(tok::equal)) {
+ if (getLangOpts().CPlusPlus && Tok.is(tok::equal)) {
const Token &KW = NextToken();
return KW.is(tok::kw_default) || KW.is(tok::kw_delete);
}
@@ -765,7 +772,7 @@
// ObjC2 allows prefix attributes on class interfaces and protocols.
// FIXME: This still needs better diagnostics. We should only accept
// attributes here, no types, etc.
- if (getLang().ObjC2 && Tok.is(tok::at)) {
+ if (getLangOpts().ObjC2 && Tok.is(tok::at)) {
SourceLocation AtLoc = ConsumeToken(); // the "@"
if (!Tok.isObjCAtKeyword(tok::objc_interface) &&
!Tok.isObjCAtKeyword(tok::objc_protocol)) {
@@ -791,7 +798,7 @@
// 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 &&
+ if (Tok.is(tok::string_literal) && getLangOpts().CPlusPlus &&
DS.getStorageClassSpec() == DeclSpec::SCS_extern &&
DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier) {
Decl *TheDecl = ParseLinkage(DS, Declarator::FileContext);
@@ -838,7 +845,7 @@
// 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().isEmpty()) {
+ if (getLangOpts().ImplicitInt && D.getDeclSpec().isEmpty()) {
const char *PrevSpec;
unsigned DiagID;
D.getMutableDeclSpec().SetTypeSpecType(DeclSpec::TST_int,
@@ -856,7 +863,7 @@
// We should have either an opening brace or, in a C++ constructor,
// we may have a colon.
if (Tok.isNot(tok::l_brace) &&
- (!getLang().CPlusPlus ||
+ (!getLangOpts().CPlusPlus ||
(Tok.isNot(tok::colon) && Tok.isNot(tok::kw_try) &&
Tok.isNot(tok::equal)))) {
Diag(Tok, diag::err_expected_fn_body);
@@ -884,7 +891,7 @@
// In delayed template parsing mode, for function template we consume the
// tokens and store them for late parsing at the end of the translation unit.
- if (getLang().DelayedTemplateParsing &&
+ if (getLangOpts().DelayedTemplateParsing &&
TemplateInfo.Kind == ParsedTemplateInfo::Template) {
MultiTemplateParamsArg TemplateParameterLists(Actions,
TemplateInfo.TemplateParams->data(),
@@ -940,7 +947,7 @@
D.getMutableDeclSpec().abort();
if (Tok.is(tok::equal)) {
- assert(getLang().CPlusPlus && "Only C++ function definitions have '='");
+ assert(getLangOpts().CPlusPlus && "Only C++ function definitions have '='");
ConsumeToken();
Actions.ActOnFinishFunctionBody(Res, 0, false);
@@ -948,7 +955,7 @@
bool Delete = false;
SourceLocation KWLoc;
if (Tok.is(tok::kw_delete)) {
- Diag(Tok, getLang().CPlusPlus0x ?
+ Diag(Tok, getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_deleted_function :
diag::ext_deleted_function);
@@ -956,7 +963,7 @@
Actions.SetDeclDeleted(Res, KWLoc);
Delete = true;
} else if (Tok.is(tok::kw_default)) {
- Diag(Tok, getLang().CPlusPlus0x ?
+ Diag(Tok, getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_defaulted_function :
diag::ext_defaulted_function);
@@ -1240,7 +1247,7 @@
0, /*IsTypename*/true))
return true;
if (!SS.isSet()) {
- if (getLang().MicrosoftExt)
+ if (getLangOpts().MicrosoftExt)
Diag(Tok.getLocation(), diag::warn_expected_qualified_after_typename);
else
Diag(Tok.getLocation(), diag::err_expected_qualified_after_typename);
@@ -1291,7 +1298,7 @@
bool wasScopeAnnotation = Tok.is(tok::annot_cxxscope);
CXXScopeSpec SS;
- if (getLang().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext))
return true;
@@ -1323,7 +1330,7 @@
return false;
}
- if (!getLang().CPlusPlus) {
+ if (!getLangOpts().CPlusPlus) {
// If we're in C, we can't have :: tokens at all (the lexer won't return
// them). If the identifier is not a type, then it can't be scope either,
// just early exit.
@@ -1402,7 +1409,7 @@
/// Note that this routine emits an error if you call it with ::new or ::delete
/// as the current tokens, so only call it in contexts where these are invalid.
bool Parser::TryAnnotateCXXScopeToken(bool EnteringContext) {
- assert(getLang().CPlusPlus &&
+ assert(getLangOpts().CPlusPlus &&
"Call sites of this function should be guarded by checking for C++");
assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon) ||
(Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) ||
Modified: cfe/branches/tooling/lib/Rewrite/HTMLPrint.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Rewrite/HTMLPrint.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Rewrite/HTMLPrint.cpp (original)
+++ cfe/branches/tooling/lib/Rewrite/HTMLPrint.cpp Mon Mar 19 14:02:20 2012
@@ -55,7 +55,7 @@
}
void HTMLPrinter::Initialize(ASTContext &context) {
- R.setSourceMgr(context.getSourceManager(), context.getLangOptions());
+ R.setSourceMgr(context.getSourceManager(), context.getLangOpts());
}
void HTMLPrinter::HandleTranslationUnit(ASTContext &Ctx) {
Modified: cfe/branches/tooling/lib/Rewrite/HTMLRewrite.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Rewrite/HTMLRewrite.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Rewrite/HTMLRewrite.cpp (original)
+++ cfe/branches/tooling/lib/Rewrite/HTMLRewrite.cpp Mon Mar 19 14:02:20 2012
@@ -360,7 +360,7 @@
const SourceManager &SM = PP.getSourceManager();
const llvm::MemoryBuffer *FromFile = SM.getBuffer(FID);
- Lexer L(FID, FromFile, SM, PP.getLangOptions());
+ Lexer L(FID, FromFile, SM, PP.getLangOpts());
const char *BufferStart = L.getBufferStart();
// Inform the preprocessor that we want to retain comments as tokens, so we
@@ -450,7 +450,7 @@
std::vector<Token> TokenStream;
const llvm::MemoryBuffer *FromFile = SM.getBuffer(FID);
- Lexer L(FID, FromFile, SM, PP.getLangOptions());
+ Lexer L(FID, FromFile, SM, PP.getLangOpts());
// Lex all the tokens in raw mode, to avoid entering #includes or expanding
// macros.
Modified: cfe/branches/tooling/lib/Rewrite/RewriteMacros.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Rewrite/RewriteMacros.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Rewrite/RewriteMacros.cpp (original)
+++ cfe/branches/tooling/lib/Rewrite/RewriteMacros.cpp Mon Mar 19 14:02:20 2012
@@ -66,7 +66,7 @@
// 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.
const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
- Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOptions());
+ Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOpts());
// Switch on comment lexing because we really do want them.
RawLex.SetCommentRetentionState(true);
@@ -91,7 +91,7 @@
SourceManager &SM = PP.getSourceManager();
Rewriter Rewrite;
- Rewrite.setSourceMgr(SM, PP.getLangOptions());
+ Rewrite.setSourceMgr(SM, PP.getLangOpts());
RewriteBuffer &RB = Rewrite.getEditBuffer(SM.getMainFileID());
std::vector<Token> RawTokens;
Modified: cfe/branches/tooling/lib/Rewrite/RewriteModernObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Rewrite/RewriteModernObjC.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Rewrite/RewriteModernObjC.cpp (original)
+++ cfe/branches/tooling/lib/Rewrite/RewriteModernObjC.cpp Mon Mar 19 14:02:20 2012
@@ -110,6 +110,12 @@
llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCWrittenInterfaces;
llvm::SmallPtrSet<TagDecl*, 8> TagsDefinedInIvarDecls;
SmallVector<ObjCInterfaceDecl*, 32> ObjCInterfacesSeen;
+ /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
+ SmallVector<ObjCInterfaceDecl*, 8> DefinedNonLazyClasses;
+
+ /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
+ llvm::SmallVector<ObjCCategoryDecl*, 8> DefinedNonLazyCategories;
+
SmallVector<Stmt *, 32> Stmts;
SmallVector<int, 8> ObjCBcLabelNo;
// Remember all the @protocol(<expr>) expressions.
@@ -120,9 +126,9 @@
// Block expressions.
SmallVector<BlockExpr *, 32> Blocks;
SmallVector<int, 32> InnerDeclRefsCount;
- SmallVector<BlockDeclRefExpr *, 32> InnerDeclRefs;
+ SmallVector<DeclRefExpr *, 32> InnerDeclRefs;
- SmallVector<BlockDeclRefExpr *, 32> BlockDeclRefs;
+ SmallVector<DeclRefExpr *, 32> BlockDeclRefs;
// Block related declarations.
SmallVector<ValueDecl *, 8> BlockByCopyDecls;
@@ -327,7 +333,7 @@
// Block specific rewrite rules.
void RewriteBlockPointerDecl(NamedDecl *VD);
void RewriteByRefVar(VarDecl *VD);
- Stmt *RewriteBlockDeclRefExpr(Expr *VD);
+ Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD);
Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE);
void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
@@ -336,6 +342,8 @@
void RewriteObjCFieldDecl(FieldDecl *fieldDecl, std::string &Result);
+ bool RewriteObjCFieldDeclType(QualType &Type, std::string &Result);
+
void RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
std::string &Result);
@@ -380,6 +388,7 @@
virtual void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
std::string &Result);
virtual void RewriteMetaDataIntoBuffer(std::string &Result);
+ virtual void WriteImageInfo(std::string &Result);
virtual void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl,
std::string &Result);
@@ -405,7 +414,7 @@
StringRef FunName);
FunctionDecl *SynthBlockInitFunctionDecl(StringRef name);
Stmt *SynthBlockInitExpr(BlockExpr *Exp,
- const SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs);
+ const SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs);
// Misc. helper routines.
QualType getProtocolType();
@@ -419,7 +428,7 @@
void CollectBlockDeclRefInfo(BlockExpr *Exp);
void GetBlockDeclRefExprs(Stmt *S);
void GetInnerBlockDeclRefExprs(Stmt *S,
- SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs,
+ SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs,
llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts);
// We avoid calling Type::isBlockPointerType(), since it operates on the
@@ -514,6 +523,12 @@
return CStyleCastExpr::Create(*Ctx, Ty, VK_RValue, Kind, E, 0, TInfo,
SourceLocation(), SourceLocation());
}
+
+ bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
+ IdentifierInfo* II = &Context->Idents.get("load");
+ Selector LoadSel = Context->Selectors.getSelector(0, &II);
+ return OD->getClassMethod(LoadSel) != 0;
+ }
};
}
@@ -611,7 +626,7 @@
MainFileStart = MainBuf->getBufferStart();
MainFileEnd = MainBuf->getBufferEnd();
- Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOptions());
+ Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts());
}
//===----------------------------------------------------------------------===//
@@ -868,6 +883,9 @@
typedefString += "\n";
typedefString += "typedef struct objc_object ";
typedefString += ForwardDecl->getNameAsString();
+ // typedef struct { } _objc_exc_Classname;
+ typedefString += ";\ntypedef struct {} _objc_exc_";
+ typedefString += ForwardDecl->getNameAsString();
typedefString += ";\n#endif\n";
}
@@ -1230,16 +1248,7 @@
std::string ResultStr;
if (!ObjCWrittenInterfaces.count(ClassDecl->getCanonicalDecl())) {
// we haven't seen a forward decl - generate a typedef.
- ResultStr = "#ifndef _REWRITER_typedef_";
- ResultStr += ClassDecl->getNameAsString();
- ResultStr += "\n";
- ResultStr += "#define _REWRITER_typedef_";
- ResultStr += ClassDecl->getNameAsString();
- ResultStr += "\n";
- ResultStr += "typedef struct objc_object ";
- ResultStr += ClassDecl->getNameAsString();
- ResultStr += ";\n#endif\n";
-
+ RewriteOneForwardClassDecl(ClassDecl, ResultStr);
RewriteIvarOffsetSymbols(ClassDecl, ResultStr);
RewriteObjCInternalStruct(ClassDecl, ResultStr);
@@ -1673,6 +1682,13 @@
return 0;
}
+static void Write_RethrowObject(std::string &buf) {
+ buf += "{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n";
+ buf += "\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n";
+ buf += "\tid rethrow;\n";
+ buf += "\t} _fin_force_rethow(_rethrow);";
+}
+
/// RewriteObjCSynchronizedStmt -
/// This routine rewrites @synchronized(expr) stmt;
/// into:
@@ -1687,66 +1703,41 @@
assert((*startBuf == '@') && "bogus @synchronized location");
std::string buf;
- buf = "objc_sync_enter((id)";
+ buf = "{ id _rethrow = 0; id _sync_obj = ";
+
const char *lparenBuf = startBuf;
while (*lparenBuf != '(') lparenBuf++;
ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
+
+ buf = "; objc_sync_enter(_sync_obj);\n";
+ buf += "try {\n\tstruct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}";
+ buf += "\n\t~_SYNC_EXIT() {objc_sync_exit(sync_exit);}";
+ buf += "\n\tid sync_exit;";
+ buf += "\n\t} _sync_exit(_sync_obj);\n";
+
// We can't use S->getSynchExpr()->getLocEnd() to find the end location, since
// the sync expression is typically a message expression that's already
// been rewritten! (which implies the SourceLocation's are invalid).
- SourceLocation endLoc = S->getSynchBody()->getLocStart();
- const char *endBuf = SM->getCharacterData(endLoc);
- while (*endBuf != ')') endBuf--;
- SourceLocation rparenLoc = startLoc.getLocWithOffset(endBuf-startBuf);
- buf = ");\n";
- // declare a new scope with two variables, _stack and _rethrow.
- buf += "/* @try scope begin */ \n{ struct _objc_exception_data {\n";
- buf += "int buf[18/*32-bit i386*/];\n";
- buf += "char *pointers[4];} _stack;\n";
- buf += "id volatile _rethrow = 0;\n";
- buf += "objc_exception_try_enter(&_stack);\n";
- buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
- ReplaceText(rparenLoc, 1, buf);
- startLoc = S->getSynchBody()->getLocEnd();
- startBuf = SM->getCharacterData(startLoc);
-
- assert((*startBuf == '}') && "bogus @synchronized block");
- SourceLocation lastCurlyLoc = startLoc;
- buf = "}\nelse {\n";
- buf += " _rethrow = objc_exception_extract(&_stack);\n";
- buf += "}\n";
- buf += "{ /* implicit finally clause */\n";
- buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
-
- std::string syncBuf;
- syncBuf += " objc_sync_exit(";
-
- Expr *syncExpr = S->getSynchExpr();
- CastKind CK = syncExpr->getType()->isObjCObjectPointerType()
- ? CK_BitCast :
- syncExpr->getType()->isBlockPointerType()
- ? CK_BlockPointerToObjCPointerCast
- : CK_CPointerToObjCPointerCast;
- syncExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
- CK, syncExpr);
- std::string syncExprBufS;
- llvm::raw_string_ostream syncExprBuf(syncExprBufS);
- syncExpr->printPretty(syncExprBuf, *Context, 0,
- PrintingPolicy(LangOpts));
- syncBuf += syncExprBuf.str();
- syncBuf += ");";
+ SourceLocation RParenExprLoc = S->getSynchBody()->getLocStart();
+ const char *RParenExprLocBuf = SM->getCharacterData(RParenExprLoc);
+ while (*RParenExprLocBuf != ')') RParenExprLocBuf--;
+ RParenExprLoc = startLoc.getLocWithOffset(RParenExprLocBuf-startBuf);
+
+ SourceLocation LBranceLoc = S->getSynchBody()->getLocStart();
+ const char *LBraceLocBuf = SM->getCharacterData(LBranceLoc);
+ assert (*LBraceLocBuf == '{');
+ ReplaceText(RParenExprLoc, (LBraceLocBuf - SM->getCharacterData(RParenExprLoc) + 1), buf);
+
+ SourceLocation startRBraceLoc = S->getSynchBody()->getLocEnd();
+ assert((*SM->getCharacterData(startRBraceLoc) == '}') &&
+ "bogus @synchronized block");
- buf += syncBuf;
- buf += "\n if (_rethrow) objc_exception_throw(_rethrow);\n";
+ buf = "} catch (id e) {_rethrow = e;}\n";
+ Write_RethrowObject(buf);
+ buf += "}\n";
buf += "}\n";
- buf += "}";
-
- ReplaceText(lastCurlyLoc, 1, buf);
- bool hasReturns = false;
- HasReturnStmts(S->getSynchBody(), hasReturns);
- if (hasReturns)
- RewriteSyncReturnStmts(S->getSynchBody(), syncBuf);
+ ReplaceText(startRBraceLoc, 1, buf);
return 0;
}
@@ -1826,167 +1817,92 @@
}
Stmt *RewriteModernObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
+ ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt();
+ bool noCatch = S->getNumCatchStmts() == 0;
+ std::string buf;
+
+ if (finalStmt) {
+ if (noCatch)
+ buf = "{ id volatile _rethrow = 0;\n";
+ else {
+ buf = "{ id volatile _rethrow = 0;\ntry {\n";
+ }
+ }
// 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);
-
- startLoc = S->getTryBody()->getLocEnd();
- startBuf = SM->getCharacterData(startLoc);
-
- assert((*startBuf == '}') && "bogus @try block");
-
- SourceLocation lastCurlyLoc = startLoc;
- if (S->getNumCatchStmts()) {
- startLoc = startLoc.getLocWithOffset(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);
- } else { /* no catch list */
- buf = "}\nelse {\n";
- buf += " _rethrow = objc_exception_extract(&_stack);\n";
- buf += "}";
- ReplaceText(lastCurlyLoc, 1, buf);
- }
- Stmt *lastCatchBody = 0;
+ if (finalStmt)
+ ReplaceText(startLoc, 1, buf);
+ else
+ // @try -> try
+ ReplaceText(startLoc, 1, "");
+
for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
ObjCAtCatchStmt *Catch = S->getCatchStmt(I);
VarDecl *catchDecl = Catch->getCatchParamDecl();
-
- if (I == 0)
- buf = "if ("; // we are generating code for the first catch clause
- else
- buf = "else if (";
+
startLoc = Catch->getLocStart();
- startBuf = SM->getCharacterData(startLoc);
-
- assert((*startBuf == '@') && "bogus @catch location");
-
- const char *lParenLoc = strchr(startBuf, '(');
-
- if (Catch->hasEllipsis()) {
- // Now rewrite the body...
- lastCatchBody = Catch->getCatchBody();
- SourceLocation bodyLoc = lastCatchBody->getLocStart();
- const char *bodyBuf = SM->getCharacterData(bodyLoc);
- assert(*SM->getCharacterData(Catch->getRParenLoc()) == ')' &&
- "bogus @catch paren location");
- assert((*bodyBuf == '{') && "bogus @catch body location");
-
- buf += "1) { id _tmp = _caught;";
- Rewrite.ReplaceText(startLoc, bodyBuf-startBuf+1, buf);
- } else if (catchDecl) {
+ bool AtRemoved = false;
+ if (catchDecl) {
QualType t = catchDecl->getType();
- if (t == Context->getObjCIdType()) {
- buf += "1) { ";
- ReplaceText(startLoc, lParenLoc-startBuf+1, buf);
- } else if (const ObjCObjectPointerType *Ptr =
- t->getAs<ObjCObjectPointerType>()) {
+ if (const ObjCObjectPointerType *Ptr = t->getAs<ObjCObjectPointerType>()) {
// Should be a pointer to a class.
ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface();
if (IDecl) {
- buf += "objc_exception_match((struct objc_class *)objc_getClass(\"";
- buf += IDecl->getNameAsString();
- buf += "\"), (struct objc_object *)_caught)) { ";
- ReplaceText(startLoc, lParenLoc-startBuf+1, buf);
+ std::string Result;
+ startBuf = SM->getCharacterData(startLoc);
+ assert((*startBuf == '@') && "bogus @catch location");
+ SourceLocation rParenLoc = Catch->getRParenLoc();
+ const char *rParenBuf = SM->getCharacterData(rParenLoc);
+
+ // _objc_exc_Foo *_e as argument to catch.
+ Result = "catch (_objc_exc_"; Result += IDecl->getNameAsString();
+ Result += " *_"; Result += catchDecl->getNameAsString();
+ Result += ")";
+ ReplaceText(startLoc, rParenBuf-startBuf+1, Result);
+ // Foo *e = (Foo *)_e;
+ Result.clear();
+ Result = "{ ";
+ Result += IDecl->getNameAsString();
+ Result += " *"; Result += catchDecl->getNameAsString();
+ Result += " = ("; Result += IDecl->getNameAsString(); Result += "*)";
+ Result += "_"; Result += catchDecl->getNameAsString();
+
+ Result += "; ";
+ SourceLocation lBraceLoc = Catch->getCatchBody()->getLocStart();
+ ReplaceText(lBraceLoc, 1, Result);
+ AtRemoved = true;
}
}
- // Now rewrite the body...
- lastCatchBody = Catch->getCatchBody();
- SourceLocation rParenLoc = Catch->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");
-
- // Here we replace ") {" with "= _caught;" (which initializes and
- // declares the @catch parameter).
- ReplaceText(rParenLoc, bodyBuf-rParenBuf+1, " = _caught;");
- } else {
- llvm_unreachable("@catch rewrite bug");
}
+ if (!AtRemoved)
+ // @catch -> catch
+ ReplaceText(startLoc, 1, "");
+
}
- // Complete the catch list...
- if (lastCatchBody) {
- SourceLocation bodyLoc = lastCatchBody->getLocEnd();
- assert(*SM->getCharacterData(bodyLoc) == '}' &&
- "bogus @catch body location");
-
- // Insert the last (implicit) else clause *before* the right curly brace.
- bodyLoc = bodyLoc.getLocWithOffset(-1);
- buf = "} /* last catch end */\n";
- buf += "else {\n";
- buf += " _rethrow = _caught;\n";
- buf += " objc_exception_try_exit(&_stack);\n";
- buf += "} } /* @catch end */\n";
- if (!S->getFinallyStmt())
- buf += "}\n";
- InsertText(bodyLoc, buf);
-
- // Set lastCurlyLoc
- lastCurlyLoc = lastCatchBody->getLocEnd();
- }
- if (ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt()) {
- startLoc = finalStmt->getLocStart();
- startBuf = SM->getCharacterData(startLoc);
- assert((*startBuf == '@') && "bogus @finally start");
-
- ReplaceText(startLoc, 8, "/* @finally */");
+ if (finalStmt) {
+ buf.clear();
+ if (noCatch)
+ buf = "catch (id e) {_rethrow = e;}\n";
+ else
+ buf = "}\ncatch (id e) {_rethrow = e;}\n";
+ SourceLocation startFinalLoc = finalStmt->getLocStart();
+ ReplaceText(startFinalLoc, 8, buf);
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.getLocWithOffset(1);
- InsertText(startLoc, " if (!_rethrow) objc_exception_try_exit(&_stack);\n");
- endLoc = endLoc.getLocWithOffset(-1);
- InsertText(endLoc, " if (_rethrow) objc_exception_throw(_rethrow);\n");
-
- // Set lastCurlyLoc
- lastCurlyLoc = body->getLocEnd();
-
- // Now check for any return/continue/go statements within the @try.
- WarnAboutReturnGotoStmts(S->getTryBody());
- } else { /* no finally clause - make sure we synthesize an implicit one */
- buf = "{ /* implicit finally clause */\n";
- buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
- buf += " if (_rethrow) objc_exception_throw(_rethrow);\n";
- buf += "}";
- ReplaceText(lastCurlyLoc, 1, buf);
+ SourceLocation startFinalBodyLoc = body->getLocStart();
+ buf.clear();
+ Write_RethrowObject(buf);
+ ReplaceText(startFinalBodyLoc, 1, buf);
+ SourceLocation endFinalBodyLoc = body->getLocEnd();
+ ReplaceText(endFinalBodyLoc, 1, "}\n}");
// Now check for any return/continue/go statements within the @try.
- // The implicit finally clause won't called if the @try contains any
- // jump statements.
- bool hasReturns = false;
- HasReturnStmts(S->getTryBody(), hasReturns);
- if (hasReturns)
- RewriteTryReturnStmts(S->getTryBody());
- }
- // Now emit the final closing curly brace...
- lastCurlyLoc = lastCurlyLoc.getLocWithOffset(1);
- InsertText(lastCurlyLoc, " } /* @try scope end */\n");
+ WarnAboutReturnGotoStmts(S->getTryBody());
+ }
+
return 0;
}
@@ -2004,8 +1920,8 @@
/* void objc_exception_throw(id) __attribute__((noreturn)); */
if (S->getThrowExpr())
buf = "objc_exception_throw(";
- else // add an implicit argument
- buf = "objc_exception_throw(_caught";
+ else
+ buf = "throw";
// handle "@ throw" correctly.
const char *wBuf = strchr(startBuf, 'w');
@@ -2015,7 +1931,8 @@
const char *semiBuf = strchr(startBuf, ';');
assert((*semiBuf == ';') && "@throw: can't find ';'");
SourceLocation semiLoc = startLoc.getLocWithOffset(semiBuf-startBuf);
- ReplaceText(semiLoc, 1, ");");
+ if (S->getThrowExpr())
+ ReplaceText(semiLoc, 1, ");");
return 0;
}
@@ -2060,7 +1977,7 @@
// Create a reference to the objc_msgSend() declaration.
DeclRefExpr *DRE =
- new (Context) DeclRefExpr(FD, msgSendType, VK_LValue, SourceLocation());
+ new (Context) DeclRefExpr(FD, false, msgSendType, VK_LValue, SourceLocation());
// Now, we cast the reference to a pointer to the objc_msgSend type.
QualType pToFunc = Context->getPointerType(msgSendType);
@@ -2573,7 +2490,7 @@
VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
SourceLocation(), &Context->Idents.get(S),
strType, 0, SC_Static, SC_None);
- DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, strType, VK_LValue,
+ DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, strType, VK_LValue,
SourceLocation());
Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf,
Context->getPointerType(DRE->getType()),
@@ -2701,6 +2618,7 @@
NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
CK_BitCast,
new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+ false,
Context->getObjCIdType(),
VK_RValue,
SourceLocation()))
@@ -2742,7 +2660,7 @@
SynthSuperContructorFunctionDecl();
// Simulate a contructor call...
DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
- superType, VK_LValue,
+ false, superType, VK_LValue,
SourceLocation());
SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
InitExprs.size(),
@@ -2812,6 +2730,7 @@
NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
CK_BitCast,
new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+ false,
Context->getObjCIdType(),
VK_RValue, SourceLocation()))
); // set the 'receiver'.
@@ -2851,7 +2770,7 @@
SynthSuperContructorFunctionDecl();
// Simulate a contructor call...
DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
- superType, VK_LValue,
+ false, superType, VK_LValue,
SourceLocation());
SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
InitExprs.size(),
@@ -3003,7 +2922,7 @@
QualType msgSendType = MsgSendFlavor->getType();
// Create a reference to the objc_msgSend() declaration.
- DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, msgSendType,
+ DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
VK_LValue, SourceLocation());
// Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid).
@@ -3039,7 +2958,8 @@
// method's return type.
// Create a reference to the objc_msgSend_stret() declaration.
- DeclRefExpr *STDRE = new (Context) DeclRefExpr(MsgSendStretFlavor, msgSendType,
+ DeclRefExpr *STDRE = new (Context) DeclRefExpr(MsgSendStretFlavor,
+ false, msgSendType,
VK_LValue, SourceLocation());
// Need to cast objc_msgSend_stret to "void *" (see above comment).
cast = NoTypeInfoCStyleCastExpr(Context,
@@ -3122,13 +3042,14 @@
/// The forward references (and metadata) are generated in
/// RewriteModernObjC::HandleTranslationUnit().
Stmt *RewriteModernObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
- std::string Name = "_OBJC_PROTOCOL_" + Exp->getProtocol()->getNameAsString();
+ std::string Name = "_OBJC_PROTOCOL_REFERENCE_$_" +
+ Exp->getProtocol()->getNameAsString();
IdentifierInfo *ID = &Context->Idents.get(Name);
VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
SourceLocation(), ID, getProtocolType(), 0,
SC_Extern, SC_None);
- DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, getProtocolType(), VK_LValue,
- SourceLocation());
+ DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, false, getProtocolType(),
+ VK_LValue, SourceLocation());
Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf,
Context->getPointerType(DRE->getType()),
VK_RValue, OK_Ordinary, SourceLocation());
@@ -3168,14 +3089,15 @@
return false;
}
-/// RewriteObjCFieldDecl - This routine rewrites a field into the buffer.
+/// RewriteObjCFieldDeclType - This routine rewrites a type into the buffer.
/// It handles elaborated types, as well as enum types in the process.
-void RewriteModernObjC::RewriteObjCFieldDecl(FieldDecl *fieldDecl,
- std::string &Result) {
- QualType Type = fieldDecl->getType();
- std::string Name = fieldDecl->getNameAsString();
-
- if (Type->isRecordType()) {
+bool RewriteModernObjC::RewriteObjCFieldDeclType(QualType &Type,
+ std::string &Result) {
+ if (Type->isArrayType()) {
+ QualType ElemTy = Context->getBaseElementType(Type);
+ return RewriteObjCFieldDeclType(ElemTy, Result);
+ }
+ else if (Type->isRecordType()) {
RecordDecl *RD = Type->getAs<RecordType>()->getDecl();
if (RD->isCompleteDefinition()) {
if (RD->isStruct())
@@ -3184,23 +3106,22 @@
Result += "\n\tunion ";
else
assert(false && "class not allowed as an ivar type");
-
+
Result += RD->getName();
if (TagsDefinedInIvarDecls.count(RD)) {
// This struct is already defined. Do not write its definition again.
- Result += " "; Result += Name; Result += ";\n";
- return;
+ Result += " ";
+ return true;
}
TagsDefinedInIvarDecls.insert(RD);
Result += " {\n";
for (RecordDecl::field_iterator i = RD->field_begin(),
- e = RD->field_end(); i != e; ++i) {
+ e = RD->field_end(); i != e; ++i) {
FieldDecl *FD = *i;
RewriteObjCFieldDecl(FD, Result);
}
Result += "\t} ";
- Result += Name; Result += ";\n";
- return;
+ return true;
}
}
else if (Type->isEnumeralType()) {
@@ -3210,8 +3131,8 @@
Result += ED->getName();
if (TagsDefinedInIvarDecls.count(ED)) {
// This enum is already defined. Do not write its definition again.
- Result += " "; Result += Name; Result += ";\n";
- return;
+ Result += " ";
+ return true;
}
TagsDefinedInIvarDecls.insert(ED);
@@ -3224,19 +3145,43 @@
Result += ",\n";
}
Result += "\t} ";
- Result += Name; Result += ";\n";
- return;
+ return true;
}
}
Result += "\t";
convertObjCTypeToCStyleType(Type);
+ return false;
+}
+
+
+/// RewriteObjCFieldDecl - This routine rewrites a field into the buffer.
+/// It handles elaborated types, as well as enum types in the process.
+void RewriteModernObjC::RewriteObjCFieldDecl(FieldDecl *fieldDecl,
+ std::string &Result) {
+ QualType Type = fieldDecl->getType();
+ std::string Name = fieldDecl->getNameAsString();
- Type.getAsStringInternal(Name, Context->getPrintingPolicy());
+ bool EleboratedType = RewriteObjCFieldDeclType(Type, Result);
+ if (!EleboratedType)
+ Type.getAsStringInternal(Name, Context->getPrintingPolicy());
Result += Name;
if (fieldDecl->isBitField()) {
Result += " : "; Result += utostr(fieldDecl->getBitWidthValue(*Context));
}
+ else if (EleboratedType && Type->isArrayType()) {
+ CanQualType CType = Context->getCanonicalType(Type);
+ while (isa<ArrayType>(CType)) {
+ if (const ConstantArrayType *CAT = Context->getAsConstantArrayType(CType)) {
+ Result += "[";
+ llvm::APInt Dim = CAT->getSize();
+ Result += utostr(Dim.getZExtValue());
+ Result += "]";
+ }
+ CType = CType->getAs<ArrayType>()->getElementType();
+ }
+ }
+
Result += ";\n";
}
@@ -3301,7 +3246,17 @@
for (llvm::SmallPtrSet<ObjCIvarDecl *, 8>::iterator i = Ivars.begin(),
e = Ivars.end(); i != e; i++) {
ObjCIvarDecl *IvarDecl = (*i);
- Result += "\nextern unsigned long OBJC_IVAR_$_";
+ Result += "\n";
+ if (LangOpts.MicrosoftExt)
+ Result += "__declspec(allocate(\".objc_ivar$B\")) ";
+ if (LangOpts.MicrosoftExt &&
+ IvarDecl->getAccessControl() != ObjCIvarDecl::Private &&
+ IvarDecl->getAccessControl() != ObjCIvarDecl::Package) {
+ const ObjCInterfaceDecl *CDecl = IvarDecl->getContainingInterface();
+ if (CDecl->getImplementation())
+ Result += "__declspec(dllexport) ";
+ }
+ Result += "extern unsigned long OBJC_IVAR_$_";
Result += CDecl->getName(); Result += "_";
Result += IvarDecl->getName(); Result += ";";
}
@@ -3663,21 +3618,25 @@
// Need to copy-in the inner copied-in variables not actually used in this
// block.
for (int j = 0; j < InnerDeclRefsCount[i]; j++) {
- BlockDeclRefExpr *Exp = InnerDeclRefs[count++];
+ DeclRefExpr *Exp = InnerDeclRefs[count++];
ValueDecl *VD = Exp->getDecl();
BlockDeclRefs.push_back(Exp);
- if (!Exp->isByRef() && !BlockByCopyDeclsPtrSet.count(VD)) {
- BlockByCopyDeclsPtrSet.insert(VD);
- BlockByCopyDecls.push_back(VD);
+ if (!VD->hasAttr<BlocksAttr>()) {
+ if (!BlockByCopyDeclsPtrSet.count(VD)) {
+ BlockByCopyDeclsPtrSet.insert(VD);
+ BlockByCopyDecls.push_back(VD);
+ }
+ continue;
}
- if (Exp->isByRef() && !BlockByRefDeclsPtrSet.count(VD)) {
+
+ if (!BlockByRefDeclsPtrSet.count(VD)) {
BlockByRefDeclsPtrSet.insert(VD);
BlockByRefDecls.push_back(VD);
}
+
// imported objects in the inner blocks not used in the outer
// blocks must be copied/disposed in the outer block as well.
- if (Exp->isByRef() ||
- VD->getType()->isObjCObjectPointerType() ||
+ if (VD->getType()->isObjCObjectPointerType() ||
VD->getType()->isBlockPointerType())
ImportedBlockDecls.insert(VD);
}
@@ -3765,25 +3724,17 @@
GetBlockDeclRefExprs(*CI);
}
// Handle specific things.
- if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(S)) {
- // FIXME: Handle enums.
- if (!isa<FunctionDecl>(CDRE->getDecl()))
- BlockDeclRefs.push_back(CDRE);
- }
- else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S))
- if (HasLocalVariableExternalStorage(DRE->getDecl())) {
- BlockDeclRefExpr *BDRE =
- new (Context)BlockDeclRefExpr(cast<VarDecl>(DRE->getDecl()),
- DRE->getType(),
- VK_LValue, DRE->getLocation(), false);
- BlockDeclRefs.push_back(BDRE);
+ if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S))
+ if (DRE->refersToEnclosingLocal() &&
+ HasLocalVariableExternalStorage(DRE->getDecl())) {
+ BlockDeclRefs.push_back(DRE);
}
return;
}
void RewriteModernObjC::GetInnerBlockDeclRefExprs(Stmt *S,
- SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs,
+ SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs,
llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts) {
for (Stmt::child_range CI = S->children(); CI; ++CI)
if (*CI) {
@@ -3800,15 +3751,15 @@
}
// Handle specific things.
- if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(S)) {
- if (!isa<FunctionDecl>(CDRE->getDecl()) &&
- !InnerContexts.count(CDRE->getDecl()->getDeclContext()))
- InnerBlockDeclRefs.push_back(CDRE);
- }
- else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
- if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
- if (Var->isFunctionOrMethodVarDecl())
- ImportedLocalExternalDecls.insert(Var);
+ if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
+ if (DRE->refersToEnclosingLocal()) {
+ if (!isa<FunctionDecl>(DRE->getDecl()) &&
+ !InnerContexts.count(DRE->getDecl()->getDeclContext()))
+ InnerBlockDeclRefs.push_back(DRE);
+ if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
+ if (Var->isFunctionOrMethodVarDecl())
+ ImportedLocalExternalDecls.insert(Var);
+ }
}
return;
@@ -3870,9 +3821,6 @@
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
CPT = DRE->getType()->getAs<BlockPointerType>();
- } else if (const BlockDeclRefExpr *CDRE =
- dyn_cast<BlockDeclRefExpr>(BlockExp)) {
- CPT = CDRE->getType()->getAs<BlockPointerType>();
} else if (const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
CPT = MExpr->getType()->getAs<BlockPointerType>();
}
@@ -3973,7 +3921,7 @@
}
// We need to return the rewritten expression to handle cases where the
-// BlockDeclRefExpr is embedded in another expression being rewritten.
+// DeclRefExpr is embedded in another expression being rewritten.
// For example:
//
// int main() {
@@ -3981,21 +3929,15 @@
// __block int i;
//
// void (^myblock)() = ^() {
-// [f test]; // f is a BlockDeclRefExpr embedded in a message (which is being rewritten).
+// [f test]; // f is a DeclRefExpr embedded in a message (which is being rewritten).
// i = 77;
// };
//}
-Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(Expr *DeclRefExp) {
+Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) {
// Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR
// for each DeclRefExp where BYREFVAR is name of the variable.
- ValueDecl *VD;
- bool isArrow = true;
- if (BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(DeclRefExp))
- VD = BDRE->getDecl();
- else {
- VD = cast<DeclRefExpr>(DeclRefExp)->getDecl();
- isArrow = false;
- }
+ ValueDecl *VD = DeclRefExp->getDecl();
+ bool isArrow = DeclRefExp->refersToEnclosingLocal();
FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
SourceLocation(),
@@ -4489,7 +4431,7 @@
if (BlockDeclRefs.size()) {
// Unique all "by copy" declarations.
for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
- if (!BlockDeclRefs[i]->isByRef()) {
+ if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
@@ -4497,7 +4439,7 @@
}
// Unique all "by ref" declarations.
for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
- if (BlockDeclRefs[i]->isByRef()) {
+ if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
@@ -4505,7 +4447,7 @@
}
// Find any imported blocks...they will need special attention.
for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
- if (BlockDeclRefs[i]->isByRef() ||
+ if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
BlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
BlockDeclRefs[i]->getType()->isBlockPointerType())
ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
@@ -4521,7 +4463,7 @@
}
Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
- const SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs) {
+ const SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs) {
const BlockDecl *block = Exp->getBlockDecl();
Blocks.push_back(Exp);
@@ -4531,9 +4473,9 @@
int countOfInnerDecls = 0;
if (!InnerBlockDeclRefs.empty()) {
for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
- BlockDeclRefExpr *Exp = InnerBlockDeclRefs[i];
+ DeclRefExpr *Exp = InnerBlockDeclRefs[i];
ValueDecl *VD = Exp->getDecl();
- if (!Exp->isByRef() && !BlockByCopyDeclsPtrSet.count(VD)) {
+ if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
// We need to save the copied-in variables in nested
// blocks because it is needed at the end for some of the API generations.
// See SynthesizeBlockLiterals routine.
@@ -4542,7 +4484,7 @@
BlockByCopyDeclsPtrSet.insert(VD);
BlockByCopyDecls.push_back(VD);
}
- if (Exp->isByRef() && !BlockByRefDeclsPtrSet.count(VD)) {
+ if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
BlockDeclRefs.push_back(Exp);
BlockByRefDeclsPtrSet.insert(VD);
@@ -4551,7 +4493,7 @@
}
// Find any imported blocks...they will need special attention.
for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
- if (InnerBlockDeclRefs[i]->isByRef() ||
+ if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
@@ -4581,15 +4523,15 @@
// Simulate a contructor call...
FD = SynthBlockInitFunctionDecl(Tag);
- DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, FType, VK_RValue,
+ DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, FType, VK_RValue,
SourceLocation());
SmallVector<Expr*, 4> InitExprs;
// Initialize the block function.
FD = SynthBlockInitFunctionDecl(Func);
- DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue,
- SourceLocation());
+ DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, false, FD->getType(),
+ VK_LValue, SourceLocation());
CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
CK_BitCast, Arg);
InitExprs.push_back(castExpr);
@@ -4603,7 +4545,7 @@
Context->VoidPtrTy, 0,
SC_Static, SC_None);
UnaryOperator *DescRefExpr =
- new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD,
+ new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, false,
Context->VoidPtrTy,
VK_LValue,
SourceLocation()),
@@ -4622,8 +4564,8 @@
if (isObjCType((*I)->getType())) {
// FIXME: Conform to ABI ([[obj retain] autorelease]).
FD = SynthBlockInitFunctionDecl((*I)->getName());
- Exp = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue,
- SourceLocation());
+ Exp = new (Context) DeclRefExpr(FD, false, FD->getType(),
+ VK_LValue, SourceLocation());
if (HasLocalVariableExternalStorage(*I)) {
QualType QT = (*I)->getType();
QT = Context->getPointerType(QT);
@@ -4632,14 +4574,14 @@
}
} else if (isTopLevelBlockPointerType((*I)->getType())) {
FD = SynthBlockInitFunctionDecl((*I)->getName());
- Arg = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue,
- SourceLocation());
+ Arg = new (Context) DeclRefExpr(FD, false, FD->getType(),
+ VK_LValue, SourceLocation());
Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
CK_BitCast, Arg);
} else {
FD = SynthBlockInitFunctionDecl((*I)->getName());
- Exp = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue,
- SourceLocation());
+ Exp = new (Context) DeclRefExpr(FD, false, FD->getType(),
+ VK_LValue, SourceLocation());
if (HasLocalVariableExternalStorage(*I)) {
QualType QT = (*I)->getType();
QT = Context->getPointerType(QT);
@@ -4666,7 +4608,7 @@
QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
FD = SynthBlockInitFunctionDecl((*I)->getName());
- Exp = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue,
+ Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
SourceLocation());
bool isNestedCapturedVar = false;
if (block)
@@ -4760,7 +4702,7 @@
}
if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
- SmallVector<BlockDeclRefExpr *, 8> InnerBlockDeclRefs;
+ SmallVector<DeclRefExpr *, 8> InnerBlockDeclRefs;
llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
InnerContexts.insert(BE->getBlockDecl());
ImportedLocalExternalDecls.clear();
@@ -4905,10 +4847,6 @@
Stmts.pop_back();
}
// Handle blocks rewriting.
- if (BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(S)) {
- if (BDRE->isByRef())
- return RewriteBlockDeclRefExpr(BDRE);
- }
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
ValueDecl *VD = DRE->getDecl();
if (VD->hasAttr<BlocksAttr>())
@@ -5085,6 +5023,23 @@
// Nothing yet.
}
+/// Write_ProtocolExprReferencedMetadata - This routine writer out the
+/// protocol reference symbols in the for of:
+/// struct _protocol_t *PROTOCOL_REF = &PROTOCOL_METADATA.
+static void Write_ProtocolExprReferencedMetadata(ASTContext *Context,
+ ObjCProtocolDecl *PDecl,
+ std::string &Result) {
+ // Also output .objc_protorefs$B section and its meta-data.
+ if (Context->getLangOpts().MicrosoftExt)
+ Result += "__declspec(allocate(\".objc_protorefs$B\")) ";
+ Result += "struct _protocol_t *";
+ Result += "_OBJC_PROTOCOL_REFERENCE_$_";
+ Result += PDecl->getNameAsString();
+ Result += " = &";
+ Result += "_OBJC_PROTOCOL_"; Result += PDecl->getNameAsString();
+ Result += ";\n";
+}
+
void RewriteModernObjC::HandleTranslationUnit(ASTContext &C) {
if (Diags.hasErrorOccurred())
return;
@@ -5094,8 +5049,10 @@
// Here's a great place to add any extra declarations that may be needed.
// Write out meta data for each @protocol(<expr>).
for (llvm::SmallPtrSet<ObjCProtocolDecl *,8>::iterator I = ProtocolExprDecls.begin(),
- E = ProtocolExprDecls.end(); I != E; ++I)
+ E = ProtocolExprDecls.end(); I != E; ++I) {
RewriteObjCProtocolMetaData(*I, Preamble);
+ Write_ProtocolExprReferencedMetadata(Context, (*I), Preamble);
+ }
InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false);
for (unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
@@ -5128,12 +5085,22 @@
// Emit metadata.
*OutFile << ResultStr;
}
+ // Emit ImageInfo;
+ {
+ std::string ResultStr;
+ WriteImageInfo(ResultStr);
+ *OutFile << ResultStr;
+ }
OutFile->flush();
}
void RewriteModernObjC::Initialize(ASTContext &context) {
InitializeCommon(context);
+ Preamble += "#ifndef __OBJC2__\n";
+ Preamble += "#define __OBJC2__\n";
+ Preamble += "#endif\n";
+
// declaring objc_selector outside the parameter list removes a silly
// scope related warning...
if (IsHeader)
@@ -5142,6 +5109,28 @@
Preamble += "struct __rw_objc_super { struct objc_object *object; ";
Preamble += "struct objc_object *superClass; ";
if (LangOpts.MicrosoftExt) {
+ // Define all sections using syntax that makes sense.
+ // These are currently generated.
+ Preamble += "\n#pragma section(\".objc_classlist$B\", long, read, write)\n";
+ Preamble += "#pragma section(\".objc_catlist$B\", long, read, write)\n";
+ Preamble += "#pragma section(\".objc_protolist$B\", long, read, write)\n";
+ Preamble += "#pragma section(\".objc_imageinfo$B\", long, read, write)\n";
+ Preamble += "#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
+ Preamble += "#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
+ Preamble += "#pragma section(\".objc_protorefs$B\", long, read, write)\n";
+ // These are generated but not necessary for functionality.
+ Preamble += "#pragma section(\".datacoal_nt$B\", long, read, write)\n";
+ Preamble += "#pragma section(\".cat_cls_meth$B\", long, read, write)\n";
+ Preamble += "#pragma section(\".inst_meth$B\", long, read, write)\n";
+ Preamble += "#pragma section(\".cls_meth$B\", long, read, write)\n";
+ Preamble += "#pragma section(\".objc_ivar$B\", long, read, write)\n";
+
+ // These need be generated for performance. Currently they are not,
+ // using API calls instead.
+ Preamble += "#pragma section(\".objc_selrefs$B\", long, read, write)\n";
+ Preamble += "#pragma section(\".objc_classrefs$B\", long, read, write)\n";
+ Preamble += "#pragma section(\".objc_superrefs$B\", long, read, write)\n";
+
// Add a constructor for creating temporary objects.
Preamble += "__rw_objc_super(struct objc_object *o, struct objc_object *s) "
": ";
@@ -5173,15 +5162,15 @@
Preamble += "(struct objc_class *);\n";
Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getMetaClass";
Preamble += "(const char *);\n";
- Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw(struct objc_object *);\n";
+ Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw(id);\n";
Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_enter(void *);\n";
Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_exit(void *);\n";
Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_exception_extract(void *);\n";
Preamble += "__OBJC_RW_DLLIMPORT int objc_exception_match";
Preamble += "(struct objc_class *, struct objc_object *);\n";
// @synchronized hooks.
- Preamble += "__OBJC_RW_DLLIMPORT void objc_sync_enter(struct objc_object *);\n";
- Preamble += "__OBJC_RW_DLLIMPORT void objc_sync_exit(struct objc_object *);\n";
+ Preamble += "__OBJC_RW_DLLIMPORT void objc_sync_enter(id);\n";
+ Preamble += "__OBJC_RW_DLLIMPORT void objc_sync_exit(id);\n";
Preamble += "__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
Preamble += "#ifndef __FASTENUMERATIONSTATE\n";
Preamble += "struct __objcFastEnumerationState {\n\t";
@@ -5367,7 +5356,7 @@
/// SEL name;
/// };
-static void WriteModernMetadataDeclarations(std::string &Result) {
+static void WriteModernMetadataDeclarations(ASTContext *Context, std::string &Result) {
static bool meta_data_declared = false;
if (meta_data_declared)
return;
@@ -5411,7 +5400,9 @@
Result += "\tunsigned int const flags;\n";
Result += "\tunsigned int instanceStart;\n";
Result += "\tunsigned int const instanceSize;\n";
- Result += "\tunsigned int const reserved; // only when building for 64bit targets\n";
+ const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
+ if (Triple.getArch() == llvm::Triple::x86_64)
+ Result += "\tunsigned int const reserved;\n";
Result += "\tconst unsigned char * const ivarLayout;\n";
Result += "\tconst char *const name;\n";
Result += "\tconst struct _method_list_t * const baseMethods;\n";
@@ -5613,8 +5604,10 @@
Result += InstanceStart; Result += ", ";
Result += InstanceSize; Result += ", \n";
Result += "\t";
- // uint32_t const reserved; // only when building for 64bit targets
- Result += "(unsigned int)0, \n\t";
+ const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
+ if (Triple.getArch() == llvm::Triple::x86_64)
+ // uint32_t const reserved; // only when building for 64bit targets
+ Result += "(unsigned int)0, \n\t";
// const uint8_t * const ivarLayout;
Result += "0, \n\t";
Result += "\""; Result += ClassName; Result += "\",\n\t";
@@ -5666,18 +5659,25 @@
if (metadata && !CDecl->getSuperClass()) {
// Need to handle a case of use of forward declaration.
- Result += "\nextern struct _class_t OBJC_CLASS_$_";
+ Result += "\n";
+ if (CDecl->getImplementation())
+ Result += "__declspec(dllexport) ";
+ Result += "extern struct _class_t OBJC_CLASS_$_";
Result += CDecl->getNameAsString();
Result += ";\n";
}
// Also, for possibility of 'super' metadata class not having been defined yet.
if (CDecl->getSuperClass()) {
- Result += "\nextern struct _class_t "; Result += VarName;
+ Result += "\n";
+ if (CDecl->getSuperClass()->getImplementation())
+ Result += "__declspec(dllexport) ";
+ Result += "extern struct _class_t ";
+ Result += VarName;
Result += CDecl->getSuperClass()->getNameAsString();
Result += ";\n";
}
- Result += "\nstruct _class_t "; Result += VarName; Result += CDecl->getNameAsString();
+ Result += "\n__declspec(dllexport) struct _class_t "; Result += VarName; Result += CDecl->getNameAsString();
Result += " __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
Result += "\t";
if (metadata) {
@@ -5722,14 +5722,20 @@
static void Write_category_t(RewriteModernObjC &RewriteObj, ASTContext *Context,
std::string &Result,
StringRef CatName,
- StringRef ClassName,
+ ObjCInterfaceDecl *ClassDecl,
ArrayRef<ObjCMethodDecl *> InstanceMethods,
ArrayRef<ObjCMethodDecl *> ClassMethods,
ArrayRef<ObjCProtocolDecl *> RefedProtocols,
ArrayRef<ObjCPropertyDecl *> ClassProperties) {
+
+ StringRef ClassName = ClassDecl->getNameAsString();
// must declare an extern class object in case this class is not implemented
// in this TU.
- Result += "\nextern struct _class_t ";
+ Result += "\n";
+ if (ClassDecl->getImplementation())
+ Result += "__declspec(dllexport) ";
+
+ Result += "extern struct _class_t ";
Result += "OBJC_CLASS_$_"; Result += ClassName;
Result += ";\n";
@@ -5805,7 +5811,8 @@
}
}
-static void Write_IvarOffsetVar(std::string &Result,
+static void Write_IvarOffsetVar(ASTContext *Context,
+ std::string &Result,
ArrayRef<ObjCIvarDecl *> Ivars,
StringRef VarName,
StringRef ClassName) {
@@ -5823,7 +5830,17 @@
Result += "\n";
for (unsigned i =0, e = Ivars.size(); i < e; i++) {
ObjCIvarDecl *IvarDecl = Ivars[i];
- Result += "unsigned long int "; Result += VarName;
+ if (Context->getLangOpts().MicrosoftExt)
+ Result += "__declspec(allocate(\".objc_ivar$B\")) ";
+
+ if (!Context->getLangOpts().MicrosoftExt ||
+ IvarDecl->getAccessControl() == ObjCIvarDecl::Private ||
+ IvarDecl->getAccessControl() == ObjCIvarDecl::Package)
+ Result += "unsigned long int ";
+ else
+ Result += "__declspec(dllexport) unsigned long int ";
+
+ Result += VarName;
Result += ClassName; Result += "_";
Result += IvarDecl->getName();
Result += " __attribute__ ((used, section (\"__DATA,__objc_ivar\")))";
@@ -5848,7 +5865,7 @@
StringRef VarName,
StringRef ClassName) {
if (Ivars.size() > 0) {
- Write_IvarOffsetVar(Result, Ivars, "OBJC_IVAR_$_", ClassName);
+ Write_IvarOffsetVar(Context, Result, Ivars, "OBJC_IVAR_$_", ClassName);
Result += "\nstatic ";
Write__ivar_list_t_TypeDecl(Result, Ivars.size());
@@ -5898,7 +5915,7 @@
// Do not synthesize the protocol more than once.
if (ObjCSynthesizedProtocols.count(PDecl->getCanonicalDecl()))
return;
- WriteModernMetadataDeclarations(Result);
+ WriteModernMetadataDeclarations(Context, Result);
if (ObjCProtocolDecl *Def = PDecl->getDefinition())
PDecl = Def;
@@ -5984,7 +6001,10 @@
PDecl->getNameAsString());
// Writer out root metadata for current protocol: struct _protocol_t
- Result += "\nstatic struct _protocol_t _OBJC_PROTOCOL_";
+ Result += "\n";
+ if (LangOpts.MicrosoftExt)
+ Result += "__declspec(allocate(\".datacoal_nt$B\")) ";
+ Result += "struct _protocol_t _OBJC_PROTOCOL_";
Result += PDecl->getNameAsString();
Result += " __attribute__ ((used, section (\"__DATA,__datacoal_nt,coalesced\"))) = {\n";
Result += "\t0,\n"; // id is; is null
@@ -6040,6 +6060,16 @@
}
else
Result += "\t0\n};\n";
+
+ // Use this protocol meta-data to build protocol list table in section
+ // .objc_protolist$B
+ // Unspecified visibility means 'private extern'.
+ if (LangOpts.MicrosoftExt)
+ Result += "__declspec(allocate(\".objc_protolist$B\")) ";
+ Result += "struct _protocol_t *";
+ Result += "_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->getNameAsString();
+ Result += " = &_OBJC_PROTOCOL_"; Result += PDecl->getNameAsString();
+ Result += ";\n";
// Mark this protocol as having been generated.
if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl()))
@@ -6063,7 +6093,10 @@
struct _objc_protocol *class_protocols[];
}
*/
- Result += "\nstatic struct {\n";
+ Result += "\n";
+ if (LangOpts.MicrosoftExt)
+ Result += "__declspec(allocate(\".cat_cls_meth$B\")) ";
+ Result += "static struct {\n";
Result += "\tstruct _objc_protocol_list *next;\n";
Result += "\tint protocol_count;\n";
Result += "\tstruct _objc_protocol *class_protocols[";
@@ -6110,7 +6143,7 @@
assert(false &&
"Legacy implicit interface rewriting not supported in moder abi");
- WriteModernMetadataDeclarations(Result);
+ WriteModernMetadataDeclarations(Context, Result);
SmallVector<ObjCIvarDecl *, 8> IVars;
for (ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
@@ -6267,6 +6300,9 @@
Write_class_t(Context, Result,
"OBJC_CLASS_$_",
CDecl, /*metaclass*/false);
+
+ if (ImplementationIsNonLazy(IDecl))
+ DefinedNonLazyClasses.push_back(CDecl);
}
@@ -6283,6 +6319,8 @@
RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
if (ClsDefCount > 0) {
+ if (LangOpts.MicrosoftExt)
+ Result += "__declspec(allocate(\".objc_classlist$B\")) ";
Result += "static struct _class_t *L_OBJC_LABEL_CLASS_$ [";
Result += llvm::utostr(ClsDefCount); Result += "]";
Result +=
@@ -6294,9 +6332,22 @@
Result += ",\n";
}
Result += "};\n";
+
+ if (!DefinedNonLazyClasses.empty()) {
+ if (LangOpts.MicrosoftExt)
+ Result += "__declspec(allocate(\".objc_nlclslist$B\")) \n";
+ Result += "static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t";
+ for (unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) {
+ Result += "\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString();
+ Result += ",\n";
+ }
+ Result += "};\n";
+ }
}
if (CatDefCount > 0) {
+ if (LangOpts.MicrosoftExt)
+ Result += "__declspec(allocate(\".objc_catlist$B\")) ";
Result += "static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
Result += llvm::utostr(CatDefCount); Result += "]";
Result +=
@@ -6312,13 +6363,37 @@
}
Result += "};\n";
}
+
+ if (!DefinedNonLazyCategories.empty()) {
+ if (LangOpts.MicrosoftExt)
+ Result += "__declspec(allocate(\".objc_nlcatlist$B\")) \n";
+ Result += "static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t";
+ for (unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) {
+ Result += "\t&_OBJC_$_CATEGORY_";
+ Result +=
+ DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString();
+ Result += "_$_";
+ Result += DefinedNonLazyCategories[i]->getNameAsString();
+ Result += ",\n";
+ }
+ Result += "};\n";
+ }
+}
+
+void RewriteModernObjC::WriteImageInfo(std::string &Result) {
+ if (LangOpts.MicrosoftExt)
+ Result += "__declspec(allocate(\".objc_imageinfo$B\")) \n";
+
+ Result += "static struct IMAGE_INFO { unsigned version; unsigned flag; } ";
+ // version 0, ObjCABI is 2
+ Result += "_OBJC_IMAGE_INFO = { 0, 2 };\n";
}
/// RewriteObjCCategoryImplDecl - Rewrite metadata for each category
/// implementation.
void RewriteModernObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
std::string &Result) {
- WriteModernMetadataDeclarations(Result);
+ WriteModernMetadataDeclarations(Context, Result);
ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface();
// Find category declaration for this implementation.
ObjCCategoryDecl *CDecl=0;
@@ -6369,10 +6444,10 @@
// Protocols referenced in class declaration?
// Protocol's super protocol list
std::vector<ObjCProtocolDecl *> RefedProtocols;
- const ObjCList<ObjCProtocolDecl> &Protocols = CDecl->getReferencedProtocols();
- for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
- E = Protocols.end();
- I != E; ++I) {
+ for (ObjCInterfaceDecl::protocol_iterator I = CDecl->protocol_begin(),
+ E = CDecl->protocol_end();
+
+ I != E; ++I) {
RefedProtocols.push_back(*I);
// Must write out all protocol definitions in current qualifier list,
// and in their nested qualifiers before writing out current definition.
@@ -6397,12 +6472,16 @@
Write_category_t(*this, Context, Result,
CDecl->getNameAsString(),
- ClassDecl->getNameAsString(),
+ ClassDecl,
InstanceMethods,
ClassMethods,
RefedProtocols,
ClassProperties);
+ // Determine if this category is also "non-lazy".
+ if (ImplementationIsNonLazy(IDecl))
+ DefinedNonLazyCategories.push_back(CDecl);
+
}
// RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or
@@ -6441,7 +6520,14 @@
}
*/
unsigned NumMethods = std::distance(MethodBegin, MethodEnd);
- Result += "\nstatic struct {\n";
+ Result += "\n";
+ if (LangOpts.MicrosoftExt) {
+ if (IsInstanceMethod)
+ Result += "__declspec(allocate(\".inst_meth$B\")) ";
+ else
+ Result += "__declspec(allocate(\".cls_meth$B\")) ";
+ }
+ Result += "static struct {\n";
Result += "\tstruct _objc_method_list *next_method;\n";
Result += "\tint method_count;\n";
Result += "\tstruct _objc_method method_list[";
@@ -6519,7 +6605,8 @@
VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
SourceLocation(), &Context->Idents.get(IvarOffsetName),
Context->UnsignedLongTy, 0, SC_Extern, SC_None);
- DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, Context->UnsignedLongTy, VK_LValue,
+ DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false,
+ Context->UnsignedLongTy, VK_LValue,
SourceLocation());
BinaryOperator *addExpr =
new (Context) BinaryOperator(castExpr, DRE, BO_Add,
@@ -6550,4 +6637,3 @@
ReplaceStmtWithRange(IV, Replacement, OldRange);
return Replacement;
}
-
Modified: cfe/branches/tooling/lib/Rewrite/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Rewrite/RewriteObjC.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Rewrite/RewriteObjC.cpp (original)
+++ cfe/branches/tooling/lib/Rewrite/RewriteObjC.cpp Mon Mar 19 14:02:20 2012
@@ -119,9 +119,9 @@
// Block expressions.
SmallVector<BlockExpr *, 32> Blocks;
SmallVector<int, 32> InnerDeclRefsCount;
- SmallVector<BlockDeclRefExpr *, 32> InnerDeclRefs;
+ SmallVector<DeclRefExpr *, 32> InnerDeclRefs;
- SmallVector<BlockDeclRefExpr *, 32> BlockDeclRefs;
+ SmallVector<DeclRefExpr *, 32> BlockDeclRefs;
// Block related declarations.
SmallVector<ValueDecl *, 8> BlockByCopyDecls;
@@ -320,7 +320,7 @@
// Block specific rewrite rules.
void RewriteBlockPointerDecl(NamedDecl *VD);
void RewriteByRefVar(VarDecl *VD);
- Stmt *RewriteBlockDeclRefExpr(Expr *VD);
+ Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD);
Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE);
void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
@@ -388,7 +388,7 @@
StringRef FunName);
FunctionDecl *SynthBlockInitFunctionDecl(StringRef name);
Stmt *SynthBlockInitExpr(BlockExpr *Exp,
- const SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs);
+ const SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs);
// Misc. helper routines.
QualType getProtocolType();
@@ -402,7 +402,7 @@
void CollectBlockDeclRefInfo(BlockExpr *Exp);
void GetBlockDeclRefExprs(Stmt *S);
void GetInnerBlockDeclRefExprs(Stmt *S,
- SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs,
+ SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs,
llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts);
// We avoid calling Type::isBlockPointerType(), since it operates on the
@@ -630,7 +630,7 @@
MainFileStart = MainBuf->getBufferStart();
MainFileEnd = MainBuf->getBufferEnd();
- Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOptions());
+ Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts());
}
//===----------------------------------------------------------------------===//
@@ -2045,8 +2045,8 @@
QualType msgSendType = FD->getType();
// Create a reference to the objc_msgSend() declaration.
- DeclRefExpr *DRE =
- new (Context) DeclRefExpr(FD, msgSendType, VK_LValue, SourceLocation());
+ DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, msgSendType,
+ VK_LValue, SourceLocation());
// Now, we cast the reference to a pointer to the objc_msgSend type.
QualType pToFunc = Context->getPointerType(msgSendType);
@@ -2559,7 +2559,7 @@
VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
SourceLocation(), &Context->Idents.get(S),
strType, 0, SC_Static, SC_None);
- DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, strType, VK_LValue,
+ DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, strType, VK_LValue,
SourceLocation());
Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf,
Context->getPointerType(DRE->getType()),
@@ -2687,6 +2687,7 @@
NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
CK_BitCast,
new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+ false,
Context->getObjCIdType(),
VK_RValue,
SourceLocation()))
@@ -2728,7 +2729,7 @@
SynthSuperContructorFunctionDecl();
// Simulate a contructor call...
DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
- superType, VK_LValue,
+ false, superType, VK_LValue,
SourceLocation());
SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
InitExprs.size(),
@@ -2798,6 +2799,7 @@
NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
CK_BitCast,
new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+ false,
Context->getObjCIdType(),
VK_RValue, SourceLocation()))
); // set the 'receiver'.
@@ -2837,7 +2839,7 @@
SynthSuperContructorFunctionDecl();
// Simulate a contructor call...
DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
- superType, VK_LValue,
+ false, superType, VK_LValue,
SourceLocation());
SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
InitExprs.size(),
@@ -2989,7 +2991,7 @@
QualType msgSendType = MsgSendFlavor->getType();
// Create a reference to the objc_msgSend() declaration.
- DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, msgSendType,
+ DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
VK_LValue, SourceLocation());
// Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid).
@@ -3025,7 +3027,8 @@
// method's return type.
// Create a reference to the objc_msgSend_stret() declaration.
- DeclRefExpr *STDRE = new (Context) DeclRefExpr(MsgSendStretFlavor, msgSendType,
+ DeclRefExpr *STDRE = new (Context) DeclRefExpr(MsgSendStretFlavor,
+ false, msgSendType,
VK_LValue, SourceLocation());
// Need to cast objc_msgSend_stret to "void *" (see above comment).
cast = NoTypeInfoCStyleCastExpr(Context,
@@ -3113,8 +3116,8 @@
VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
SourceLocation(), ID, getProtocolType(), 0,
SC_Extern, SC_None);
- DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, getProtocolType(), VK_LValue,
- SourceLocation());
+ DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, false, getProtocolType(),
+ VK_LValue, SourceLocation());
Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf,
Context->getPointerType(DRE->getType()),
VK_RValue, OK_Ordinary, SourceLocation());
@@ -3630,20 +3633,20 @@
// Need to copy-in the inner copied-in variables not actually used in this
// block.
for (int j = 0; j < InnerDeclRefsCount[i]; j++) {
- BlockDeclRefExpr *Exp = InnerDeclRefs[count++];
+ DeclRefExpr *Exp = InnerDeclRefs[count++];
ValueDecl *VD = Exp->getDecl();
BlockDeclRefs.push_back(Exp);
- if (!Exp->isByRef() && !BlockByCopyDeclsPtrSet.count(VD)) {
+ if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
BlockByCopyDeclsPtrSet.insert(VD);
BlockByCopyDecls.push_back(VD);
}
- if (Exp->isByRef() && !BlockByRefDeclsPtrSet.count(VD)) {
+ if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
BlockByRefDeclsPtrSet.insert(VD);
BlockByRefDecls.push_back(VD);
}
// imported objects in the inner blocks not used in the outer
// blocks must be copied/disposed in the outer block as well.
- if (Exp->isByRef() ||
+ if (VD->hasAttr<BlocksAttr>() ||
VD->getType()->isObjCObjectPointerType() ||
VD->getType()->isBlockPointerType())
ImportedBlockDecls.insert(VD);
@@ -3732,25 +3735,21 @@
GetBlockDeclRefExprs(*CI);
}
// Handle specific things.
- if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(S)) {
- // FIXME: Handle enums.
- if (!isa<FunctionDecl>(CDRE->getDecl()))
- BlockDeclRefs.push_back(CDRE);
- }
- else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S))
- if (HasLocalVariableExternalStorage(DRE->getDecl())) {
- BlockDeclRefExpr *BDRE =
- new (Context)BlockDeclRefExpr(cast<VarDecl>(DRE->getDecl()),
- DRE->getType(),
- VK_LValue, DRE->getLocation(), false);
- BlockDeclRefs.push_back(BDRE);
+ if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
+ if (DRE->refersToEnclosingLocal()) {
+ // FIXME: Handle enums.
+ if (!isa<FunctionDecl>(DRE->getDecl()))
+ BlockDeclRefs.push_back(DRE);
+ if (HasLocalVariableExternalStorage(DRE->getDecl()))
+ BlockDeclRefs.push_back(DRE);
}
+ }
return;
}
void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S,
- SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs,
+ SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs,
llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts) {
for (Stmt::child_range CI = S->children(); CI; ++CI)
if (*CI) {
@@ -3767,15 +3766,15 @@
}
// Handle specific things.
- if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(S)) {
- if (!isa<FunctionDecl>(CDRE->getDecl()) &&
- !InnerContexts.count(CDRE->getDecl()->getDeclContext()))
- InnerBlockDeclRefs.push_back(CDRE);
- }
- else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
- if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
- if (Var->isFunctionOrMethodVarDecl())
- ImportedLocalExternalDecls.insert(Var);
+ if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
+ if (DRE->refersToEnclosingLocal()) {
+ if (!isa<FunctionDecl>(DRE->getDecl()) &&
+ !InnerContexts.count(DRE->getDecl()->getDeclContext()))
+ InnerBlockDeclRefs.push_back(DRE);
+ if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
+ if (Var->isFunctionOrMethodVarDecl())
+ ImportedLocalExternalDecls.insert(Var);
+ }
}
return;
@@ -3818,9 +3817,6 @@
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
CPT = DRE->getType()->getAs<BlockPointerType>();
- } else if (const BlockDeclRefExpr *CDRE =
- dyn_cast<BlockDeclRefExpr>(BlockExp)) {
- CPT = CDRE->getType()->getAs<BlockPointerType>();
} else if (const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
CPT = MExpr->getType()->getAs<BlockPointerType>();
}
@@ -3933,17 +3929,11 @@
// i = 77;
// };
//}
-Stmt *RewriteObjC::RewriteBlockDeclRefExpr(Expr *DeclRefExp) {
+Stmt *RewriteObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) {
// Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR
// for each DeclRefExp where BYREFVAR is name of the variable.
- ValueDecl *VD;
- bool isArrow = true;
- if (BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(DeclRefExp))
- VD = BDRE->getDecl();
- else {
- VD = cast<DeclRefExpr>(DeclRefExp)->getDecl();
- isArrow = false;
- }
+ ValueDecl *VD = DeclRefExp->getDecl();
+ bool isArrow = DeclRefExp->refersToEnclosingLocal();
FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
SourceLocation(),
@@ -4437,7 +4427,7 @@
if (BlockDeclRefs.size()) {
// Unique all "by copy" declarations.
for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
- if (!BlockDeclRefs[i]->isByRef()) {
+ if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
@@ -4445,7 +4435,7 @@
}
// Unique all "by ref" declarations.
for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
- if (BlockDeclRefs[i]->isByRef()) {
+ if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
@@ -4453,7 +4443,7 @@
}
// Find any imported blocks...they will need special attention.
for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
- if (BlockDeclRefs[i]->isByRef() ||
+ if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
BlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
BlockDeclRefs[i]->getType()->isBlockPointerType())
ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
@@ -4469,7 +4459,7 @@
}
Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
- const SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs) {
+ const SmallVector<DeclRefExpr *, 8> &InnerBlockDeclRefs) {
const BlockDecl *block = Exp->getBlockDecl();
Blocks.push_back(Exp);
@@ -4479,9 +4469,9 @@
int countOfInnerDecls = 0;
if (!InnerBlockDeclRefs.empty()) {
for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
- BlockDeclRefExpr *Exp = InnerBlockDeclRefs[i];
+ DeclRefExpr *Exp = InnerBlockDeclRefs[i];
ValueDecl *VD = Exp->getDecl();
- if (!Exp->isByRef() && !BlockByCopyDeclsPtrSet.count(VD)) {
+ if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
// We need to save the copied-in variables in nested
// blocks because it is needed at the end for some of the API generations.
// See SynthesizeBlockLiterals routine.
@@ -4490,7 +4480,7 @@
BlockByCopyDeclsPtrSet.insert(VD);
BlockByCopyDecls.push_back(VD);
}
- if (Exp->isByRef() && !BlockByRefDeclsPtrSet.count(VD)) {
+ if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
BlockDeclRefs.push_back(Exp);
BlockByRefDeclsPtrSet.insert(VD);
@@ -4499,7 +4489,7 @@
}
// Find any imported blocks...they will need special attention.
for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
- if (InnerBlockDeclRefs[i]->isByRef() ||
+ if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
@@ -4529,15 +4519,15 @@
// Simulate a contructor call...
FD = SynthBlockInitFunctionDecl(Tag);
- DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, FType, VK_RValue,
+ DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, FType, VK_RValue,
SourceLocation());
SmallVector<Expr*, 4> InitExprs;
// Initialize the block function.
FD = SynthBlockInitFunctionDecl(Func);
- DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue,
- SourceLocation());
+ DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, false, FD->getType(),
+ VK_LValue, SourceLocation());
CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
CK_BitCast, Arg);
InitExprs.push_back(castExpr);
@@ -4551,7 +4541,7 @@
Context->VoidPtrTy, 0,
SC_Static, SC_None);
UnaryOperator *DescRefExpr =
- new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD,
+ new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, false,
Context->VoidPtrTy,
VK_LValue,
SourceLocation()),
@@ -4570,7 +4560,7 @@
if (isObjCType((*I)->getType())) {
// FIXME: Conform to ABI ([[obj retain] autorelease]).
FD = SynthBlockInitFunctionDecl((*I)->getName());
- Exp = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue,
+ Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
SourceLocation());
if (HasLocalVariableExternalStorage(*I)) {
QualType QT = (*I)->getType();
@@ -4580,13 +4570,13 @@
}
} else if (isTopLevelBlockPointerType((*I)->getType())) {
FD = SynthBlockInitFunctionDecl((*I)->getName());
- Arg = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue,
+ Arg = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
SourceLocation());
Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
CK_BitCast, Arg);
} else {
FD = SynthBlockInitFunctionDecl((*I)->getName());
- Exp = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue,
+ Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
SourceLocation());
if (HasLocalVariableExternalStorage(*I)) {
QualType QT = (*I)->getType();
@@ -4614,7 +4604,7 @@
QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
FD = SynthBlockInitFunctionDecl((*I)->getName());
- Exp = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue,
+ Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
SourceLocation());
bool isNestedCapturedVar = false;
if (block)
@@ -4708,7 +4698,7 @@
}
if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
- SmallVector<BlockDeclRefExpr *, 8> InnerBlockDeclRefs;
+ SmallVector<DeclRefExpr *, 8> InnerBlockDeclRefs;
llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
InnerContexts.insert(BE->getBlockDecl());
ImportedLocalExternalDecls.clear();
@@ -4853,10 +4843,6 @@
Stmts.pop_back();
}
// Handle blocks rewriting.
- if (BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(S)) {
- if (BDRE->isByRef())
- return RewriteBlockDeclRefExpr(BDRE);
- }
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
ValueDecl *VD = DRE->getDecl();
if (VD->hasAttr<BlocksAttr>())
Modified: cfe/branches/tooling/lib/Rewrite/RewriteTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Rewrite/RewriteTest.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Rewrite/RewriteTest.cpp (original)
+++ cfe/branches/tooling/lib/Rewrite/RewriteTest.cpp Mon Mar 19 14:02:20 2012
@@ -18,7 +18,7 @@
void clang::DoRewriteTest(Preprocessor &PP, raw_ostream* OS) {
SourceManager &SM = PP.getSourceManager();
- const LangOptions &LangOpts = PP.getLangOptions();
+ const LangOptions &LangOpts = PP.getLangOpts();
TokenRewriter Rewriter(SM.getMainFileID(), SM, LangOpts);
Modified: cfe/branches/tooling/lib/Sema/CodeCompleteConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/CodeCompleteConsumer.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/CodeCompleteConsumer.cpp (original)
+++ cfe/branches/tooling/lib/Sema/CodeCompleteConsumer.cpp Mon Mar 19 14:02:20 2012
@@ -400,11 +400,19 @@
}
}
+/// \brief Retrieve the effective availability of the given declaration.
+static AvailabilityResult getDeclAvailability(Decl *D) {
+ AvailabilityResult AR = D->getAvailability();
+ if (isa<EnumConstantDecl>(D))
+ AR = std::max(AR, cast<Decl>(D->getDeclContext())->getAvailability());
+ return AR;
+}
+
void CodeCompletionResult::computeCursorKindAndAvailability(bool Accessible) {
switch (Kind) {
- case RK_Declaration:
+ case RK_Declaration: {
// Set the availability based on attributes.
- switch (Declaration->getAvailability()) {
+ switch (getDeclAvailability(Declaration)) {
case AR_Available:
case AR_NotYetIntroduced:
Availability = CXAvailability_Available;
@@ -436,6 +444,7 @@
CursorKind = CXCursor_NotImplemented;
}
break;
+ }
case RK_Macro:
Availability = CXAvailability_Available;
Modified: cfe/branches/tooling/lib/Sema/DeclSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/DeclSpec.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/DeclSpec.cpp (original)
+++ cfe/branches/tooling/lib/Sema/DeclSpec.cpp Mon Mar 19 14:02:20 2012
@@ -421,7 +421,7 @@
// It seems sensible to prohibit private_extern too
// The cl_clang_storage_class_specifiers extension enables support for
// these storage-class specifiers.
- if (S.getLangOptions().OpenCL &&
+ if (S.getLangOpts().OpenCL &&
!S.getOpenCLOptions().cl_clang_storage_class_specifiers) {
switch (SC) {
case SCS_extern:
@@ -440,7 +440,7 @@
if (StorageClassSpec != SCS_unspecified) {
// Maybe this is an attempt to use C++0x 'auto' outside of C++0x mode.
bool isInvalid = true;
- if (TypeSpecType == TST_unspecified && S.getLangOptions().CPlusPlus) {
+ if (TypeSpecType == TST_unspecified && S.getLangOpts().CPlusPlus) {
if (SC == SCS_auto)
return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID);
if (StorageClassSpec == SCS_auto) {
@@ -866,7 +866,7 @@
TypeSpecType = TST_double; // _Complex -> _Complex double.
} else if (TypeSpecType == TST_int || TypeSpecType == TST_char) {
// Note that this intentionally doesn't include _Complex _Bool.
- if (!PP.getLangOptions().CPlusPlus)
+ if (!PP.getLangOpts().CPlusPlus)
Diag(D, TSTLoc, diag::ext_integer_complex);
} else if (TypeSpecType != TST_float && TypeSpecType != TST_double) {
Diag(D, TSCLoc, diag::err_invalid_complex_spec)
@@ -880,7 +880,7 @@
// class specifier, then assume this is an attempt to use C++0x's 'auto'
// type specifier.
// FIXME: Does Microsoft really support implicit int in C++?
- if (PP.getLangOptions().CPlusPlus && !PP.getLangOptions().MicrosoftExt &&
+ if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().MicrosoftExt &&
TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) {
TypeSpecType = TST_auto;
StorageClassSpec = StorageClassSpecAsWritten = SCS_unspecified;
@@ -889,9 +889,9 @@
}
// Diagnose if we've recovered from an ill-formed 'auto' storage class
// specifier in a pre-C++0x dialect of C++.
- if (!PP.getLangOptions().CPlusPlus0x && TypeSpecType == TST_auto)
+ if (!PP.getLangOpts().CPlusPlus0x && TypeSpecType == TST_auto)
Diag(D, TSTLoc, diag::ext_auto_type_specifier);
- if (PP.getLangOptions().CPlusPlus && !PP.getLangOptions().CPlusPlus0x &&
+ if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().CPlusPlus0x &&
StorageClassSpec == SCS_auto)
Diag(D, StorageClassSpecLoc, diag::warn_auto_storage_class)
<< FixItHint::CreateRemoval(StorageClassSpecLoc);
Modified: cfe/branches/tooling/lib/Sema/IdentifierResolver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/IdentifierResolver.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/IdentifierResolver.cpp (original)
+++ cfe/branches/tooling/lib/Sema/IdentifierResolver.cpp Mon Mar 19 14:02:20 2012
@@ -97,7 +97,7 @@
//===----------------------------------------------------------------------===//
IdentifierResolver::IdentifierResolver(Preprocessor &PP)
- : LangOpt(PP.getLangOptions()), PP(PP),
+ : LangOpt(PP.getLangOpts()), PP(PP),
IdDeclInfos(new IdDeclInfoMap) {
}
Modified: cfe/branches/tooling/lib/Sema/JumpDiagnostics.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/JumpDiagnostics.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/JumpDiagnostics.cpp (original)
+++ cfe/branches/tooling/lib/Sema/JumpDiagnostics.cpp Mon Mar 19 14:02:20 2012
@@ -135,7 +135,7 @@
return ScopePair(diag::note_protected_by_cleanup,
diag::note_exits_cleanup);
- if (Context.getLangOptions().ObjCAutoRefCount && VD->hasLocalStorage()) {
+ if (Context.getLangOpts().ObjCAutoRefCount && VD->hasLocalStorage()) {
switch (VD->getType().getObjCLifetime()) {
case Qualifiers::OCL_None:
case Qualifiers::OCL_ExplicitNone:
@@ -149,7 +149,7 @@
}
}
- if (Context.getLangOptions().CPlusPlus && VD->hasLocalStorage()) {
+ if (Context.getLangOpts().CPlusPlus && VD->hasLocalStorage()) {
// C++11 [stmt.dcl]p3:
// A program that jumps from a point where a variable with automatic
// storage duration is not in scope to a point where it is in scope
@@ -654,7 +654,7 @@
/// Return true if a particular note should be downgraded to a compatibility
/// warning in C++11 mode.
static bool IsCXX98CompatWarning(Sema &S, unsigned InDiagNote) {
- return S.getLangOptions().CPlusPlus0x &&
+ return S.getLangOpts().CPlusPlus0x &&
InDiagNote == diag::note_protected_by_variable_non_pod;
}
@@ -737,7 +737,7 @@
SmallVector<unsigned, 10> ToScopesError;
SmallVector<unsigned, 10> ToScopesWarning;
for (unsigned I = ToScope; I != CommonScope; I = Scopes[I].ParentScope) {
- if (S.getLangOptions().MicrosoftMode && JumpDiagWarning != 0 &&
+ if (S.getLangOpts().MicrosoftMode && JumpDiagWarning != 0 &&
IsMicrosoftJumpWarning(JumpDiagError, Scopes[I].InDiag))
ToScopesWarning.push_back(I);
else if (IsCXX98CompatWarning(S, Scopes[I].InDiag))
Modified: cfe/branches/tooling/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/Sema.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/Sema.cpp (original)
+++ cfe/branches/tooling/lib/Sema/Sema.cpp Mon Mar 19 14:02:20 2012
@@ -60,7 +60,7 @@
PrintingPolicy Sema::getPrintingPolicy(const ASTContext &Context,
const Preprocessor &PP) {
PrintingPolicy Policy = Context.getPrintingPolicy();
- Policy.Bool = Context.getLangOptions().Bool;
+ Policy.Bool = Context.getLangOpts().Bool;
if (!Policy.Bool) {
if (MacroInfo *BoolMacro = PP.getMacroInfo(&Context.Idents.get("bool"))) {
Policy.Bool = BoolMacro->isObjectLike() &&
@@ -82,8 +82,8 @@
Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
TranslationUnitKind TUKind,
CodeCompleteConsumer *CodeCompleter)
- : TheTargetAttributesSema(0), FPFeatures(pp.getLangOptions()),
- LangOpts(pp.getLangOptions()), PP(pp), Context(ctxt), Consumer(consumer),
+ : TheTargetAttributesSema(0), FPFeatures(pp.getLangOpts()),
+ LangOpts(pp.getLangOpts()), PP(pp), Context(ctxt), Consumer(consumer),
Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
CollectStats(false), ExternalSource(0), CodeCompleter(CodeCompleter),
CurContext(0), OriginalLexicalContext(0),
@@ -107,10 +107,10 @@
for (unsigned I = 0; I != NSAPI::NumNSNumberLiteralMethods; ++I)
NSNumberLiteralMethods[I] = 0;
- if (getLangOptions().ObjC1)
+ if (getLangOpts().ObjC1)
NSAPIObj.reset(new NSAPI(Context));
- if (getLangOptions().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
FieldCollector.reset(new CXXFieldCollector());
// Tell diagnostics how to render things from the AST library.
@@ -152,7 +152,7 @@
// Initialize predefined Objective-C types:
- if (PP.getLangOptions().ObjC1) {
+ if (PP.getLangOpts().ObjC1) {
// If 'SEL' does not yet refer to any declarations, make it refer to the
// predefined 'SEL'.
DeclarationName SEL = &Context.Idents.get("SEL");
@@ -265,7 +265,7 @@
if (ExprTy == TypeTy)
return Owned(E);
- if (getLangOptions().ObjCAutoRefCount)
+ if (getLangOpts().ObjCAutoRefCount)
CheckObjCARCConversion(SourceRange(), Ty, E, CCK);
// If this is a derived-to-base cast to a through a virtual base, we
@@ -673,12 +673,17 @@
return 0;
}
-Sema::SemaDiagnosticBuilder::~SemaDiagnosticBuilder() {
- if (!isActive())
- return;
-
- if (llvm::Optional<TemplateDeductionInfo*> Info = SemaRef.isSFINAEContext()) {
- switch (DiagnosticIDs::getDiagnosticSFINAEResponse(getDiagID())) {
+void Sema::EmitCurrentDiagnostic(unsigned DiagID) {
+ // FIXME: It doesn't make sense to me that DiagID is an incoming argument here
+ // and yet we also use the current diag ID on the DiagnosticsEngine. This has
+ // been made more painfully obvious by the refactor that introduced this
+ // function, but it is possible that the incoming argument can be
+ // eliminnated. If it truly cannot be (for example, there is some reentrancy
+ // issue I am not seeing yet), then there should at least be a clarifying
+ // comment somewhere.
+ if (llvm::Optional<TemplateDeductionInfo*> Info = isSFINAEContext()) {
+ switch (DiagnosticIDs::getDiagnosticSFINAEResponse(
+ Diags.getCurrentDiagID())) {
case DiagnosticIDs::SFINAE_Report:
// We'll report the diagnostic below.
break;
@@ -686,63 +691,57 @@
case DiagnosticIDs::SFINAE_SubstitutionFailure:
// Count this failure so that we know that template argument deduction
// has failed.
- ++SemaRef.NumSFINAEErrors;
- SemaRef.Diags.setLastDiagnosticIgnored();
- SemaRef.Diags.Clear();
- Clear();
+ ++NumSFINAEErrors;
+ Diags.setLastDiagnosticIgnored();
+ Diags.Clear();
return;
case DiagnosticIDs::SFINAE_AccessControl: {
// Per C++ Core Issue 1170, access control is part of SFINAE.
- // Additionally, the AccessCheckingSFINAE flag can be used to temporary
+ // Additionally, the AccessCheckingSFINAE flag can be used to temporarily
// make access control a part of SFINAE for the purposes of checking
// type traits.
- if (!SemaRef.AccessCheckingSFINAE &&
- !SemaRef.getLangOptions().CPlusPlus0x)
+ if (!AccessCheckingSFINAE && !getLangOpts().CPlusPlus0x)
break;
- SourceLocation Loc = getLocation();
+ SourceLocation Loc = Diags.getCurrentDiagLoc();
// Suppress this diagnostic.
- ++SemaRef.NumSFINAEErrors;
- SemaRef.Diags.setLastDiagnosticIgnored();
- SemaRef.Diags.Clear();
- Clear();
+ ++NumSFINAEErrors;
+ Diags.setLastDiagnosticIgnored();
+ Diags.Clear();
// Now the diagnostic state is clear, produce a C++98 compatibility
// warning.
- SemaRef.Diag(Loc, diag::warn_cxx98_compat_sfinae_access_control);
+ Diag(Loc, diag::warn_cxx98_compat_sfinae_access_control);
// The last diagnostic which Sema produced was ignored. Suppress any
// notes attached to it.
- SemaRef.Diags.setLastDiagnosticIgnored();
+ Diags.setLastDiagnosticIgnored();
return;
}
case DiagnosticIDs::SFINAE_Suppress:
// Make a copy of this suppressed diagnostic and store it with the
// template-deduction information;
- FlushCounts();
- Diagnostic DiagInfo(&SemaRef.Diags);
+ Diagnostic DiagInfo(&Diags);
if (*Info)
(*Info)->addSuppressedDiagnostic(DiagInfo.getLocation(),
- PartialDiagnostic(DiagInfo,
- SemaRef.Context.getDiagAllocator()));
+ PartialDiagnostic(DiagInfo,Context.getDiagAllocator()));
// Suppress this diagnostic.
- SemaRef.Diags.setLastDiagnosticIgnored();
- SemaRef.Diags.Clear();
- Clear();
+ Diags.setLastDiagnosticIgnored();
+ Diags.Clear();
return;
}
}
// Set up the context's printing policy based on our current state.
- SemaRef.Context.setPrintingPolicy(SemaRef.getPrintingPolicy());
+ Context.setPrintingPolicy(getPrintingPolicy());
// Emit the diagnostic.
- if (!this->Emit())
+ if (!Diags.EmitCurrentDiagnostic())
return;
// If this is not a note, and we're in a template instantiation
@@ -750,20 +749,14 @@
// we emitted an error, print a template instantiation
// backtrace.
if (!DiagnosticIDs::isBuiltinNote(DiagID) &&
- !SemaRef.ActiveTemplateInstantiations.empty() &&
- SemaRef.ActiveTemplateInstantiations.back()
- != SemaRef.LastTemplateInstantiationErrorContext) {
- SemaRef.PrintInstantiationStack();
- SemaRef.LastTemplateInstantiationErrorContext
- = SemaRef.ActiveTemplateInstantiations.back();
+ !ActiveTemplateInstantiations.empty() &&
+ ActiveTemplateInstantiations.back()
+ != LastTemplateInstantiationErrorContext) {
+ PrintInstantiationStack();
+ LastTemplateInstantiationErrorContext = ActiveTemplateInstantiations.back();
}
}
-Sema::SemaDiagnosticBuilder Sema::Diag(SourceLocation Loc, unsigned DiagID) {
- DiagnosticBuilder DB = Diags.Report(Loc, DiagID);
- return SemaDiagnosticBuilder(DB, *this, DiagID);
-}
-
Sema::SemaDiagnosticBuilder
Sema::Diag(SourceLocation Loc, const PartialDiagnostic& PD) {
SemaDiagnosticBuilder Builder(Diag(Loc, PD.getDiagID()));
Modified: cfe/branches/tooling/lib/Sema/SemaAccess.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaAccess.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaAccess.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaAccess.cpp Mon Mar 19 14:02:20 2012
@@ -1274,7 +1274,7 @@
AccessTarget &Entity) {
assert(Entity.getAccess() != AS_public && "called for public access!");
- if (S.getLangOptions().MicrosoftMode &&
+ if (S.getLangOpts().MicrosoftMode &&
IsMicrosoftUsingDeclarationAccessBug(S, Loc, Entity))
return AR_accessible;
@@ -1394,7 +1394,7 @@
Sema::AccessResult Sema::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
DeclAccessPair Found) {
- if (!getLangOptions().AccessControl ||
+ if (!getLangOpts().AccessControl ||
!E->getNamingClass() ||
Found.getAccess() == AS_public)
return AR_accessible;
@@ -1410,7 +1410,7 @@
/// access which has now been resolved to a member.
Sema::AccessResult Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
DeclAccessPair Found) {
- if (!getLangOptions().AccessControl ||
+ if (!getLangOpts().AccessControl ||
Found.getAccess() == AS_public)
return AR_accessible;
@@ -1428,7 +1428,7 @@
Sema::AccessResult Sema::CheckDestructorAccess(SourceLocation Loc,
CXXDestructorDecl *Dtor,
const PartialDiagnostic &PDiag) {
- if (!getLangOptions().AccessControl)
+ if (!getLangOpts().AccessControl)
return AR_accessible;
// There's never a path involved when checking implicit destructor access.
@@ -1451,7 +1451,7 @@
const InitializedEntity &Entity,
AccessSpecifier Access,
bool IsCopyBindingRefToTemp) {
- if (!getLangOptions().AccessControl ||
+ if (!getLangOpts().AccessControl ||
Access == AS_public)
return AR_accessible;
@@ -1498,7 +1498,7 @@
CXXConstructorDecl *Constructor,
AccessSpecifier Access,
PartialDiagnostic PD) {
- if (!getLangOptions().AccessControl ||
+ if (!getLangOpts().AccessControl ||
Access == AS_public)
return AR_accessible;
@@ -1517,7 +1517,7 @@
NamedDecl *Target,
const PartialDiagnostic &Diag) {
AccessSpecifier Access = Target->getAccess();
- if (!getLangOptions().AccessControl ||
+ if (!getLangOpts().AccessControl ||
Access == AS_public)
return AR_accessible;
@@ -1536,7 +1536,7 @@
CXXRecordDecl *NamingClass,
DeclAccessPair Found,
bool Diagnose) {
- if (!getLangOptions().AccessControl ||
+ if (!getLangOpts().AccessControl ||
!NamingClass ||
Found.getAccess() == AS_public)
return AR_accessible;
@@ -1556,7 +1556,7 @@
Expr *ObjectExpr,
Expr *ArgExpr,
DeclAccessPair Found) {
- if (!getLangOptions().AccessControl ||
+ if (!getLangOpts().AccessControl ||
Found.getAccess() == AS_public)
return AR_accessible;
@@ -1574,7 +1574,7 @@
Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr,
DeclAccessPair Found) {
- if (!getLangOptions().AccessControl ||
+ if (!getLangOpts().AccessControl ||
Found.getAccess() == AS_none ||
Found.getAccess() == AS_public)
return AR_accessible;
@@ -1606,7 +1606,7 @@
unsigned DiagID,
bool ForceCheck,
bool ForceUnprivileged) {
- if (!ForceCheck && !getLangOptions().AccessControl)
+ if (!ForceCheck && !getLangOpts().AccessControl)
return AR_accessible;
if (Path.Access == AS_public)
@@ -1635,7 +1635,7 @@
/// Checks access to all the declarations in the given result set.
void Sema::CheckLookupAccess(const LookupResult &R) {
- assert(getLangOptions().AccessControl
+ assert(getLangOpts().AccessControl
&& "performing access check without access control");
assert(R.getNamingClass() && "performing access check without naming class");
Modified: cfe/branches/tooling/lib/Sema/SemaAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaAttr.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaAttr.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaAttr.cpp Mon Mar 19 14:02:20 2012
@@ -378,7 +378,7 @@
FPFeatures.fp_contract = 0;
break;
case tok::OOS_DEFAULT:
- FPFeatures.fp_contract = getLangOptions().DefaultFPContract;
+ FPFeatures.fp_contract = getLangOpts().DefaultFPContract;
break;
}
}
Modified: cfe/branches/tooling/lib/Sema/SemaCXXScopeSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaCXXScopeSpec.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaCXXScopeSpec.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaCXXScopeSpec.cpp Mon Mar 19 14:02:20 2012
@@ -13,6 +13,7 @@
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Template.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/ExprCXX.h"
@@ -186,7 +187,7 @@
///
/// \param NNS a dependent nested name specifier.
CXXRecordDecl *Sema::getCurrentInstantiationOf(NestedNameSpecifier *NNS) {
- assert(getLangOptions().CPlusPlus && "Only callable in C++");
+ assert(getLangOpts().CPlusPlus && "Only callable in C++");
assert(NNS->isDependent() && "Only dependent nested-name-specifier allowed");
if (!NNS->getAsType())
@@ -209,43 +210,52 @@
DeclContext *DC) {
assert(DC != 0 && "given null context");
- if (TagDecl *tag = dyn_cast<TagDecl>(DC)) {
- // If this is a dependent type, then we consider it complete.
- if (tag->isDependentContext())
- return false;
+ TagDecl *tag = dyn_cast<TagDecl>(DC);
- // If we're currently defining this type, then lookup into the
- // type is okay: don't complain that it isn't complete yet.
- QualType type = Context.getTypeDeclType(tag);
- const TagType *tagType = type->getAs<TagType>();
- if (tagType && tagType->isBeingDefined())
- return false;
+ // If this is a dependent type, then we consider it complete.
+ if (!tag || tag->isDependentContext())
+ return false;
- SourceLocation loc = SS.getLastQualifierNameLoc();
- if (loc.isInvalid()) loc = SS.getRange().getBegin();
+ // If we're currently defining this type, then lookup into the
+ // type is okay: don't complain that it isn't complete yet.
+ QualType type = Context.getTypeDeclType(tag);
+ const TagType *tagType = type->getAs<TagType>();
+ if (tagType && tagType->isBeingDefined())
+ return false;
- // The type must be complete.
- if (RequireCompleteType(loc, type,
- PDiag(diag::err_incomplete_nested_name_spec)
- << SS.getRange())) {
- SS.SetInvalid(SS.getRange());
- return true;
- }
+ SourceLocation loc = SS.getLastQualifierNameLoc();
+ if (loc.isInvalid()) loc = SS.getRange().getBegin();
- // Fixed enum types are complete, but they aren't valid as scopes
- // until we see a definition, so awkwardly pull out this special
- // case.
- if (const EnumType *enumType = dyn_cast_or_null<EnumType>(tagType)) {
- if (!enumType->getDecl()->isCompleteDefinition()) {
- Diag(loc, diag::err_incomplete_nested_name_spec)
- << type << SS.getRange();
- SS.SetInvalid(SS.getRange());
- return true;
- }
- }
+ // The type must be complete.
+ if (RequireCompleteType(loc, type,
+ PDiag(diag::err_incomplete_nested_name_spec)
+ << SS.getRange())) {
+ SS.SetInvalid(SS.getRange());
+ return true;
}
- return false;
+ // Fixed enum types are complete, but they aren't valid as scopes
+ // until we see a definition, so awkwardly pull out this special
+ // case.
+ const EnumType *enumType = dyn_cast_or_null<EnumType>(tagType);
+ if (!enumType || enumType->getDecl()->isCompleteDefinition())
+ return false;
+
+ // Try to instantiate the definition, if this is a specialization of an
+ // enumeration temploid.
+ EnumDecl *ED = enumType->getDecl();
+ if (EnumDecl *Pattern = ED->getInstantiatedFromMemberEnum()) {
+ MemberSpecializationInfo *MSI = ED->getMemberSpecializationInfo();
+ if (MSI->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)
+ return InstantiateEnum(loc, ED, Pattern,
+ getTemplateInstantiationArgs(ED),
+ TSK_ImplicitInstantiation);
+ }
+
+ Diag(loc, diag::err_incomplete_nested_name_spec)
+ << type << SS.getRange();
+ SS.SetInvalid(SS.getRange());
+ return true;
}
bool Sema::ActOnCXXGlobalScopeSpecifier(Scope *S, SourceLocation CCLoc,
@@ -274,11 +284,11 @@
return true;
else if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(SD)) {
if (TD->getUnderlyingType()->isRecordType() ||
- (Context.getLangOptions().CPlusPlus0x &&
+ (Context.getLangOpts().CPlusPlus0x &&
TD->getUnderlyingType()->isEnumeralType()))
return true;
} else if (isa<RecordDecl>(SD) ||
- (Context.getLangOptions().CPlusPlus0x && isa<EnumDecl>(SD)))
+ (Context.getLangOpts().CPlusPlus0x && isa<EnumDecl>(SD)))
return true;
return false;
@@ -502,8 +512,8 @@
if ((Corrected = CorrectTypo(Found.getLookupNameInfo(),
Found.getLookupKind(), S, &SS, Validator,
LookupCtx, EnteringContext))) {
- std::string CorrectedStr(Corrected.getAsString(getLangOptions()));
- std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOptions()));
+ std::string CorrectedStr(Corrected.getAsString(getLangOpts()));
+ std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts()));
if (LookupCtx)
Diag(Found.getNameLoc(), diag::err_no_member_suggest)
<< Name << LookupCtx << CorrectedQuotedStr << SS.getRange()
@@ -652,7 +662,7 @@
// public:
// void foo() { D::foo2(); }
// };
- if (getLangOptions().MicrosoftExt) {
+ if (getLangOpts().MicrosoftExt) {
DeclContext *DC = LookupCtx ? LookupCtx : CurContext;
if (DC->isDependentContext() && DC->isFunctionOrMethod()) {
SS.Extend(Context, &Identifier, IdentifierLoc, CCLoc);
@@ -705,7 +715,7 @@
QualType T = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc());
if (!T->isDependentType() && !T->getAs<TagType>()) {
Diag(DS.getTypeSpecTypeLoc(), diag::err_expected_class)
- << T << getLangOptions().CPlusPlus;
+ << T << getLangOpts().CPlusPlus;
return true;
}
Modified: cfe/branches/tooling/lib/Sema/SemaCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaCast.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaCast.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaCast.cpp Mon Mar 19 14:02:20 2012
@@ -118,7 +118,7 @@
}
void checkObjCARCConversion(Sema::CheckedConversionKind CCK) {
- assert(Self.getLangOptions().ObjCAutoRefCount);
+ assert(Self.getLangOpts().ObjCAutoRefCount);
Expr *src = SrcExpr.get();
if (Self.CheckObjCARCConversion(OpRange, DestType, src, CCK) ==
@@ -222,7 +222,7 @@
if (D.isInvalidType())
return ExprError();
- if (getLangOptions().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
// Check that there are no default arguments (C++ only).
CheckExtraCXXDefaultArguments(D);
}
@@ -462,7 +462,7 @@
// If the only checking we care about is for Objective-C lifetime qualifiers,
// and we're not in ARC mode, there's nothing to check.
if (!CheckCVR && CheckObjCLifetime &&
- !Self.Context.getLangOptions().ObjCAutoRefCount)
+ !Self.Context.getLangOpts().ObjCAutoRefCount)
return false;
// Casting away constness is defined in C++ 5.2.11p8 with reference to
@@ -710,7 +710,7 @@
diagnoseBadCast(Self, msg, CT_Reinterpret, OpRange, SrcExpr.get(),
DestType, /*listInitialization=*/false);
}
- } else if (tcr == TC_Success && Self.getLangOptions().ObjCAutoRefCount) {
+ } else if (tcr == TC_Success && Self.getLangOpts().ObjCAutoRefCount) {
checkObjCARCConversion(Sema::CCK_OtherCast);
}
}
@@ -772,7 +772,7 @@
} else if (tcr == TC_Success) {
if (Kind == CK_BitCast)
checkCastAlign();
- if (Self.getLangOptions().ObjCAutoRefCount)
+ if (Self.getLangOpts().ObjCAutoRefCount)
checkObjCARCConversion(Sema::CCK_OtherCast);
} else if (Kind == CK_BitCast) {
checkCastAlign();
@@ -1664,7 +1664,7 @@
// integral type size doesn't matter.
if ((Self.Context.getTypeSize(SrcType) >
Self.Context.getTypeSize(DestType)) &&
- !Self.getLangOptions().MicrosoftExt) {
+ !Self.getLangOpts().MicrosoftExt) {
msg = diag::err_bad_reinterpret_cast_small_int;
return TC_Failed;
}
@@ -1738,7 +1738,7 @@
// FIXME: Conditionally-supported behavior should be configurable in the
// TargetInfo or similar.
Self.Diag(OpRange.getBegin(),
- Self.getLangOptions().CPlusPlus0x ?
+ Self.getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
<< OpRange;
return TC_Success;
@@ -1747,7 +1747,7 @@
if (DestType->isFunctionPointerType()) {
// See above.
Self.Diag(OpRange.getBegin(),
- Self.getLangOptions().CPlusPlus0x ?
+ Self.getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)
<< OpRange;
return TC_Success;
@@ -1858,7 +1858,7 @@
}
}
- if (Self.getLangOptions().ObjCAutoRefCount && tcr == TC_Success)
+ if (Self.getLangOpts().ObjCAutoRefCount && tcr == TC_Success)
checkObjCARCConversion(CCK);
if (tcr != TC_Success && msg != 0) {
@@ -1887,7 +1887,7 @@
/// Check the semantics of a C-style cast operation, in C.
void CastOperation::CheckCStyleCast() {
- assert(!Self.getLangOptions().CPlusPlus);
+ assert(!Self.getLangOpts().CPlusPlus);
// C-style casts can resolve __unknown_any types.
if (claimPlaceholder(BuiltinType::UnknownAny)) {
@@ -2033,7 +2033,7 @@
}
// ARC imposes extra restrictions on casts.
- if (Self.getLangOptions().ObjCAutoRefCount) {
+ if (Self.getLangOpts().ObjCAutoRefCount) {
checkObjCARCConversion(Sema::CCK_CStyleCast);
if (SrcExpr.isInvalid())
return;
@@ -2078,7 +2078,7 @@
Op.DestRange = CastTypeInfo->getTypeLoc().getSourceRange();
Op.OpRange = SourceRange(LPLoc, CastExpr->getLocEnd());
- if (getLangOptions().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
Op.CheckCXXCStyleCast(/*FunctionalStyle=*/ false,
isa<InitListExpr>(CastExpr));
} else {
Modified: cfe/branches/tooling/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaChecking.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaChecking.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaChecking.cpp Mon Mar 19 14:02:20 2012
@@ -43,7 +43,7 @@
SourceLocation Sema::getLocationOfStringLiteralByte(const StringLiteral *SL,
unsigned ByteNo) const {
return SL->getLocationOfByte(ByteNo, PP.getSourceManager(),
- PP.getLangOptions(), PP.getTargetInfo());
+ PP.getLangOpts(), PP.getTargetInfo());
}
/// Checks that a call expression's argument count is the desired number.
@@ -983,6 +983,7 @@
DRE->getQualifierLoc(),
SourceLocation(),
NewBuiltinDecl,
+ /*enclosing*/ false,
DRE->getLocation(),
NewBuiltinDecl->getType(),
DRE->getValueKind());
@@ -1677,6 +1678,8 @@
const analyze_format_string::ConversionSpecifier &CS,
const char *startSpecifier, unsigned specifierLen);
+ virtual void HandlePosition(const char *startPos, unsigned posLen);
+
virtual void HandleInvalidPosition(const char *startSpecifier,
unsigned specifierLen,
analyze_format_string::PositionContext p);
@@ -1756,7 +1759,7 @@
const analyze_format_string::LengthModifier &LM,
const char *startSpecifier, unsigned specifierLen) {
EmitFormatDiagnostic(S.PDiag(diag::warn_format_non_standard) << LM.toString()
- << "length modifier",
+ << 0,
getLocationOfByte(LM.getStart()),
/*IsStringLocation*/true,
getSpecifierRange(startSpecifier, specifierLen));
@@ -1766,7 +1769,7 @@
const analyze_format_string::ConversionSpecifier &CS,
const char *startSpecifier, unsigned specifierLen) {
EmitFormatDiagnostic(S.PDiag(diag::warn_format_non_standard) << CS.toString()
- << "conversion specifier",
+ << 1,
getLocationOfByte(CS.getStart()),
/*IsStringLocation*/true,
getSpecifierRange(startSpecifier, specifierLen));
@@ -1783,6 +1786,14 @@
getSpecifierRange(startSpecifier, specifierLen));
}
+void CheckFormatHandler::HandlePosition(const char *startPos,
+ unsigned posLen) {
+ EmitFormatDiagnostic(S.PDiag(diag::warn_format_non_standard_positional_arg),
+ getLocationOfByte(startPos),
+ /*IsStringLocation*/true,
+ getSpecifierRange(startPos, posLen));
+}
+
void
CheckFormatHandler::HandleInvalidPosition(const char *startPos, unsigned posLen,
analyze_format_string::PositionContext p) {
@@ -2203,7 +2214,7 @@
LM.getLength())));
if (!FS.hasStandardLengthModifier())
HandleNonStandardLengthModifier(LM, startSpecifier, specifierLen);
- if (!FS.hasStandardConversionSpecifier(S.getLangOptions()))
+ if (!FS.hasStandardConversionSpecifier(S.getLangOpts()))
HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
if (!FS.hasStandardLengthConversionCombination())
HandleNonStandardConversionSpecification(LM, CS, startSpecifier,
@@ -2246,7 +2257,7 @@
// We may be able to offer a FixItHint if it is a supported type.
PrintfSpecifier fixedFS = FS;
- bool success = fixedFS.fixType(Ex->getType(), S.getLangOptions(),
+ bool success = fixedFS.fixType(Ex->getType(), S.getLangOpts(),
S.Context, IsObjCLiteral);
if (success) {
@@ -2396,7 +2407,7 @@
if (!FS.hasStandardLengthModifier())
HandleNonStandardLengthModifier(LM, startSpecifier, specifierLen);
- if (!FS.hasStandardConversionSpecifier(S.getLangOptions()))
+ if (!FS.hasStandardConversionSpecifier(S.getLangOpts()))
HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
if (!FS.hasStandardLengthConversionCombination())
HandleNonStandardConversionSpecification(LM, CS, startSpecifier,
@@ -2414,7 +2425,7 @@
const analyze_scanf::ScanfArgTypeResult &ATR = FS.getArgType(S.Context);
if (ATR.isValid() && !ATR.matchesType(S.Context, Ex->getType())) {
ScanfSpecifier fixedFS = FS;
- bool success = fixedFS.fixType(Ex->getType(), S.getLangOptions(),
+ bool success = fixedFS.fixType(Ex->getType(), S.getLangOpts(),
S.Context);
if (success) {
@@ -2485,7 +2496,7 @@
inFunctionCall);
if (!analyze_format_string::ParsePrintfString(H, Str, Str + StrLen,
- getLangOptions()))
+ getLangOpts()))
H.DoneProcessing();
} else if (Type == FST_Scanf) {
CheckScanfHandler H(*this, FExpr, OrigFormatExpr, firstDataArg,
@@ -2494,7 +2505,7 @@
inFunctionCall);
if (!analyze_format_string::ParseScanfString(H, Str, Str + StrLen,
- getLangOptions()))
+ getLangOpts()))
H.DoneProcessing();
} // TODO: handle other formats
}
@@ -2880,7 +2891,7 @@
// Perform checking for returned stack addresses, local blocks,
// label addresses or references to temporaries.
if (lhsType->isPointerType() ||
- (!getLangOptions().ObjCAutoRefCount && lhsType->isBlockPointerType())) {
+ (!getLangOpts().ObjCAutoRefCount && lhsType->isBlockPointerType())) {
stackE = EvalAddr(RetValExp, refVars);
} else if (lhsType->isReferenceType()) {
stackE = EvalVal(RetValExp, refVars);
@@ -4064,8 +4075,11 @@
if ((E->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNotNull)
== Expr::NPCK_GNUNull) && Target->isIntegerType()) {
- S.Diag(E->getExprLoc(), diag::warn_impcast_null_pointer_to_integer)
- << E->getSourceRange() << clang::SourceRange(CC);
+ SourceLocation Loc = E->getSourceRange().getBegin();
+ if (Loc.isMacroID())
+ Loc = S.SourceMgr.getImmediateExpansionRange(Loc).first;
+ S.Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
+ << T << Loc << clang::SourceRange(CC);
return;
}
@@ -4127,7 +4141,7 @@
// In C, we pretend that the type of an EnumConstantDecl is its enumeration
// type, to give us better diagnostics.
QualType SourceType = E->getType();
- if (!S.getLangOptions().CPlusPlus) {
+ if (!S.getLangOpts().CPlusPlus) {
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
if (EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
EnumDecl *Enum = cast<EnumDecl>(ECD->getDeclContext());
@@ -4327,7 +4341,7 @@
if (CheckParameterNames &&
Param->getIdentifier() == 0 &&
!Param->isImplicit() &&
- !getLangOptions().CPlusPlus)
+ !getLangOpts().CPlusPlus)
Diag(Param->getLocation(), diag::err_parameter_name_omitted);
// C99 6.7.5.3p12:
@@ -4664,12 +4678,6 @@
return considerVariable(var, ref, owner);
}
- if (BlockDeclRefExpr *ref = dyn_cast<BlockDeclRefExpr>(e)) {
- owner.Variable = ref->getDecl();
- owner.setLocsFrom(ref);
- return true;
- }
-
if (MemberExpr *member = dyn_cast<MemberExpr>(e)) {
if (member->isArrow()) return false;
@@ -4726,11 +4734,6 @@
Capturer = ref;
}
- void VisitBlockDeclRefExpr(BlockDeclRefExpr *ref) {
- if (ref->getDecl() == Variable && !Capturer)
- Capturer = ref;
- }
-
void VisitObjCIvarRefExpr(ObjCIvarRefExpr *ref) {
if (Capturer) return;
Visit(ref->getBase());
Modified: cfe/branches/tooling/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaCodeComplete.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaCodeComplete.cpp Mon Mar 19 14:02:20 2012
@@ -533,7 +533,7 @@
// Filter out any unwanted results.
if (Filter && !(this->*Filter)(ND)) {
// Check whether it is interesting as a nested-name-specifier.
- if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
+ if (AllowNestedNameSpecifiers && SemaRef.getLangOpts().CPlusPlus &&
IsNestedNameSpecifier(ND) &&
(Filter != &ResultBuilder::IsMember ||
(isa<CXXRecordDecl>(ND) &&
@@ -553,7 +553,7 @@
// In C, there is no way to refer to a hidden name.
// FIXME: This isn't true; we can find a tag name hidden by an ordinary
// name if we introduce the tag type.
- if (!SemaRef.getLangOptions().CPlusPlus)
+ if (!SemaRef.getLangOpts().CPlusPlus)
return true;
DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getRedeclContext();
@@ -732,7 +732,7 @@
}
void ResultBuilder::MaybeAddConstructorResults(Result R) {
- if (!SemaRef.getLangOptions().CPlusPlus || !R.Declaration ||
+ if (!SemaRef.getLangOpts().CPlusPlus || !R.Declaration ||
!CompletionContext.wantConstructorResults())
return;
@@ -988,9 +988,9 @@
ND = cast<NamedDecl>(ND->getUnderlyingDecl());
unsigned IDNS = Decl::IDNS_Ordinary;
- if (SemaRef.getLangOptions().CPlusPlus)
+ if (SemaRef.getLangOpts().CPlusPlus)
IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
- else if (SemaRef.getLangOptions().ObjC1) {
+ else if (SemaRef.getLangOpts().ObjC1) {
if (isa<ObjCIvarDecl>(ND))
return true;
}
@@ -1006,9 +1006,9 @@
return false;
unsigned IDNS = Decl::IDNS_Ordinary;
- if (SemaRef.getLangOptions().CPlusPlus)
+ if (SemaRef.getLangOpts().CPlusPlus)
IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
- else if (SemaRef.getLangOptions().ObjC1) {
+ else if (SemaRef.getLangOpts().ObjC1) {
if (isa<ObjCIvarDecl>(ND))
return true;
}
@@ -1033,7 +1033,7 @@
ND = cast<NamedDecl>(ND->getUnderlyingDecl());
unsigned IDNS = Decl::IDNS_Ordinary;
- if (SemaRef.getLangOptions().CPlusPlus)
+ if (SemaRef.getLangOpts().CPlusPlus)
IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
return (ND->getIdentifierNamespace() & IDNS) &&
@@ -1135,7 +1135,7 @@
break;
}
- if (!C.getLangOptions().CPlusPlus)
+ if (!C.getLangOpts().CPlusPlus)
return false;
// FIXME: We could perform more analysis here to determine whether a
@@ -1165,8 +1165,8 @@
}
bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
- if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
- (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
+ if ((SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryName(ND)) ||
+ (!SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
return false;
QualType T = getDeclUsageType(SemaRef.Context, ND);
@@ -1176,7 +1176,7 @@
T = SemaRef.Context.getBaseElementType(T);
return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
T->isObjCIdType() ||
- (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
+ (SemaRef.getLangOpts().CPlusPlus && T->isRecordType());
}
bool ResultBuilder::IsImpossibleToSatisfy(NamedDecl *ND) const {
@@ -1464,7 +1464,7 @@
typedef CodeCompletionResult Result;
switch (CCC) {
case Sema::PCC_Namespace:
- if (SemaRef.getLangOptions().CPlusPlus) {
+ if (SemaRef.getLangOpts().CPlusPlus) {
if (Results.includeCodePatterns()) {
// namespace <identifier> { declarations }
Builder.AddTypedTextChunk("namespace");
@@ -1509,14 +1509,14 @@
}
}
- if (SemaRef.getLangOptions().ObjC1)
+ if (SemaRef.getLangOpts().ObjC1)
AddObjCTopLevelResults(Results, true);
AddTypedefResult(Results);
// Fall through
case Sema::PCC_Class:
- if (SemaRef.getLangOptions().CPlusPlus) {
+ if (SemaRef.getLangOpts().CPlusPlus) {
// Using declaration
Builder.AddTypedTextChunk("using");
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
@@ -1560,7 +1560,7 @@
case Sema::PCC_Template:
case Sema::PCC_MemberTemplate:
- if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
+ if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns()) {
// template < parameters >
Builder.AddTypedTextChunk("template");
Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
@@ -1569,32 +1569,32 @@
Results.AddResult(Result(Builder.TakeString()));
}
- AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
- AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
+ AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
+ AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
break;
case Sema::PCC_ObjCInterface:
- AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
- AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
- AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
+ AddObjCInterfaceResults(SemaRef.getLangOpts(), Results, true);
+ AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
+ AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
break;
case Sema::PCC_ObjCImplementation:
- AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
- AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
- AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
+ AddObjCImplementationResults(SemaRef.getLangOpts(), Results, true);
+ AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
+ AddFunctionSpecifiers(CCC, SemaRef.getLangOpts(), Results);
break;
case Sema::PCC_ObjCInstanceVariableList:
- AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
+ AddObjCVisibilityResults(SemaRef.getLangOpts(), Results, true);
break;
case Sema::PCC_RecoveryInFunction:
case Sema::PCC_Statement: {
AddTypedefResult(Results);
- if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns() &&
- SemaRef.getLangOptions().CXXExceptions) {
+ if (SemaRef.getLangOpts().CPlusPlus && Results.includeCodePatterns() &&
+ SemaRef.getLangOpts().CXXExceptions) {
Builder.AddTypedTextChunk("try");
Builder.AddChunk(CodeCompletionString::CK_LeftBrace);
Builder.AddPlaceholderChunk("statements");
@@ -1610,14 +1610,14 @@
Builder.AddChunk(CodeCompletionString::CK_RightBrace);
Results.AddResult(Result(Builder.TakeString()));
}
- if (SemaRef.getLangOptions().ObjC1)
+ if (SemaRef.getLangOpts().ObjC1)
AddObjCStatementResults(Results, true);
if (Results.includeCodePatterns()) {
// if (condition) { statements }
Builder.AddTypedTextChunk("if");
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
- if (SemaRef.getLangOptions().CPlusPlus)
+ if (SemaRef.getLangOpts().CPlusPlus)
Builder.AddPlaceholderChunk("condition");
else
Builder.AddPlaceholderChunk("expression");
@@ -1631,7 +1631,7 @@
// switch (condition) { }
Builder.AddTypedTextChunk("switch");
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
- if (SemaRef.getLangOptions().CPlusPlus)
+ if (SemaRef.getLangOpts().CPlusPlus)
Builder.AddPlaceholderChunk("condition");
else
Builder.AddPlaceholderChunk("expression");
@@ -1661,7 +1661,7 @@
/// while (condition) { statements }
Builder.AddTypedTextChunk("while");
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
- if (SemaRef.getLangOptions().CPlusPlus)
+ if (SemaRef.getLangOpts().CPlusPlus)
Builder.AddPlaceholderChunk("condition");
else
Builder.AddPlaceholderChunk("expression");
@@ -1687,7 +1687,7 @@
// for ( for-init-statement ; condition ; expression ) { statements }
Builder.AddTypedTextChunk("for");
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
- if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
+ if (SemaRef.getLangOpts().CPlusPlus || SemaRef.getLangOpts().C99)
Builder.AddPlaceholderChunk("init-statement");
else
Builder.AddPlaceholderChunk("init-expression");
@@ -1752,11 +1752,11 @@
// Fall through (for statement expressions).
case Sema::PCC_ForInit:
case Sema::PCC_Condition:
- AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
+ AddStorageSpecifiers(CCC, SemaRef.getLangOpts(), Results);
// Fall through: conditions and statements can have expressions.
case Sema::PCC_ParenthesizedExpression:
- if (SemaRef.getLangOptions().ObjCAutoRefCount &&
+ if (SemaRef.getLangOpts().ObjCAutoRefCount &&
CCC == Sema::PCC_ParenthesizedExpression) {
// (__bridge <type>)<expression>
Builder.AddTypedTextChunk("__bridge");
@@ -1785,7 +1785,7 @@
// Fall through
case Sema::PCC_Expression: {
- if (SemaRef.getLangOptions().CPlusPlus) {
+ if (SemaRef.getLangOpts().CPlusPlus) {
// 'this', if we're in a non-static member function.
addThisCompletion(SemaRef, Results);
@@ -1799,7 +1799,7 @@
Builder.AddTypedTextChunk("false");
Results.AddResult(Result(Builder.TakeString()));
- if (SemaRef.getLangOptions().RTTI) {
+ if (SemaRef.getLangOpts().RTTI) {
// dynamic_cast < type-id > ( expression )
Builder.AddTypedTextChunk("dynamic_cast");
Builder.AddChunk(CodeCompletionString::CK_LeftAngle);
@@ -1841,7 +1841,7 @@
Builder.AddChunk(CodeCompletionString::CK_RightParen);
Results.AddResult(Result(Builder.TakeString()));
- if (SemaRef.getLangOptions().RTTI) {
+ if (SemaRef.getLangOpts().RTTI) {
// typeid ( expression-or-type )
Builder.AddResultTypeChunk("std::type_info");
Builder.AddTypedTextChunk("typeid");
@@ -1889,7 +1889,7 @@
Builder.AddPlaceholderChunk("expression");
Results.AddResult(Result(Builder.TakeString()));
- if (SemaRef.getLangOptions().CXXExceptions) {
+ if (SemaRef.getLangOpts().CXXExceptions) {
// throw expression
Builder.AddResultTypeChunk("void");
Builder.AddTypedTextChunk("throw");
@@ -1900,7 +1900,7 @@
// FIXME: Rethrow?
- if (SemaRef.getLangOptions().CPlusPlus0x) {
+ if (SemaRef.getLangOpts().CPlusPlus0x) {
// nullptr
Builder.AddResultTypeChunk("std::nullptr_t");
Builder.AddTypedTextChunk("nullptr");
@@ -1932,7 +1932,7 @@
}
}
- if (SemaRef.getLangOptions().ObjC1) {
+ if (SemaRef.getLangOpts().ObjC1) {
// Add "super", if we're in an Objective-C class with a superclass.
if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl()) {
// The interface can be NULL.
@@ -1967,10 +1967,10 @@
break;
}
- if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
- AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
+ if (WantTypesInContext(CCC, SemaRef.getLangOpts()))
+ AddTypeSpecifierResults(SemaRef.getLangOpts(), Results);
- if (SemaRef.getLangOptions().CPlusPlus && CCC != Sema::PCC_Type)
+ if (SemaRef.getLangOpts().CPlusPlus && CCC != Sema::PCC_Type)
Results.AddResult(Result("operator"));
}
@@ -2016,7 +2016,7 @@
CodeCompletionBuilder &Result) {
if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
if (Sentinel->getSentinel() == 0) {
- if (Context.getLangOptions().ObjC1 &&
+ if (Context.getLangOpts().ObjC1 &&
Context.Idents.get("nil").hasMacroDefinition())
Result.AddTextChunk(", nil");
else if (Context.Idents.get("NULL").hasMacroDefinition())
@@ -2872,7 +2872,7 @@
M != MEnd; ++M) {
Results.AddResult(Result(M->first,
getMacroUsagePriority(M->first->getName(),
- PP.getLangOptions(),
+ PP.getLangOpts(),
TargetTypeIsPointer)));
}
@@ -2932,8 +2932,8 @@
return CodeCompletionContext::CCC_Recovery;
case Sema::PCC_ForInit:
- if (S.getLangOptions().CPlusPlus || S.getLangOptions().C99 ||
- S.getLangOptions().ObjC1)
+ if (S.getLangOpts().CPlusPlus || S.getLangOpts().C99 ||
+ S.getLangOpts().ObjC1)
return CodeCompletionContext::CCC_ParenthesizedExpression;
else
return CodeCompletionContext::CCC_Expression;
@@ -3113,12 +3113,12 @@
case PCC_Expression:
case PCC_ForInit:
case PCC_Condition:
- if (WantTypesInContext(CompletionContext, getLangOptions()))
+ if (WantTypesInContext(CompletionContext, getLangOpts()))
Results.setFilter(&ResultBuilder::IsOrdinaryName);
else
Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
- if (getLangOptions().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
MaybeAddOverrideCalls(*this, /*InContext=*/0, Results);
break;
@@ -3147,7 +3147,7 @@
case PCC_Statement:
case PCC_RecoveryInFunction:
if (S->getFnParent())
- AddPrettyFunctionResults(PP.getLangOptions(), Results);
+ AddPrettyFunctionResults(PP.getLangOpts(), Results);
break;
case PCC_Namespace:
@@ -3192,10 +3192,10 @@
// Type qualifiers can come after names.
Results.AddResult(Result("const"));
Results.AddResult(Result("volatile"));
- if (getLangOptions().C99)
+ if (getLangOpts().C99)
Results.AddResult(Result("restrict"));
- if (getLangOptions().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
if (AllowNonIdentifiers) {
Results.AddResult(Result("operator"));
}
@@ -3266,7 +3266,7 @@
Results.setFilter(&ResultBuilder::IsObjCCollection);
else if (Data.IntegralConstantExpression)
Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
- else if (WantTypesInContext(PCC_Expression, getLangOptions()))
+ else if (WantTypesInContext(PCC_Expression, getLangOpts()))
Results.setFilter(&ResultBuilder::IsOrdinaryName);
else
Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
@@ -3295,7 +3295,7 @@
if (S->getFnParent() &&
!Data.ObjCCollection &&
!Data.IntegralConstantExpression)
- AddPrettyFunctionResults(PP.getLangOptions(), Results);
+ AddPrettyFunctionResults(PP.getLangOpts(), Results);
if (CodeCompleter->includeMacros())
AddMacroResults(PP, Results, PreferredTypeIsPointer);
@@ -3308,7 +3308,7 @@
void Sema::CodeCompletePostfixExpression(Scope *S, ExprResult E) {
if (E.isInvalid())
CodeCompleteOrdinaryName(S, PCC_RecoveryInFunction);
- else if (getLangOptions().ObjC1)
+ else if (getLangOpts().ObjC1)
CodeCompleteObjCInstanceMessage(S, E.take(), 0, 0, false);
}
@@ -3470,7 +3470,7 @@
LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
CodeCompleter->includeGlobals());
- if (getLangOptions().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
if (!Results.empty()) {
// The "template" keyword can follow "->" or "." in the grammar.
// However, we only want to suggest the template keyword if something
@@ -3590,7 +3590,7 @@
Results.AddResult("const");
if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
Results.AddResult("volatile");
- if (getLangOptions().C99 &&
+ if (getLangOpts().C99 &&
!(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
Results.AddResult("restrict");
Results.ExitScope();
@@ -3655,7 +3655,7 @@
}
}
- if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
+ if (getLangOpts().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
// If there are no prior enumerators in C++, check whether we have to
// qualify the names of the enumerators that we suggest, because they
// may not be visible in this scope.
@@ -3755,7 +3755,7 @@
else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
if (FDecl) {
- if (!getLangOptions().CPlusPlus ||
+ if (!getLangOpts().CPlusPlus ||
!FDecl->getType()->getAs<FunctionProtoType>())
Results.push_back(ResultCandidate(FDecl));
else
@@ -3883,7 +3883,7 @@
Builder.AddTextChunk("if");
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
- if (getLangOptions().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
Builder.AddPlaceholderChunk("condition");
else
Builder.AddPlaceholderChunk("expression");
@@ -3901,7 +3901,7 @@
Results.ExitScope();
if (S->getFnParent())
- AddPrettyFunctionResults(PP.getLangOptions(), Results);
+ AddPrettyFunctionResults(PP.getLangOpts(), Results);
if (CodeCompleter->includeMacros())
AddMacroResults(PP, Results);
@@ -4085,7 +4085,7 @@
CodeCompleter->includeGlobals());
// Add any type specifiers
- AddTypeSpecifierResults(getLangOptions(), Results);
+ AddTypeSpecifierResults(getLangOpts(), Results);
Results.ExitScope();
HandleCodeCompleteResults(this, CodeCompleter,
@@ -4350,9 +4350,9 @@
CodeCompletionContext::CCC_Other);
Results.EnterNewScope();
if (isa<ObjCImplDecl>(CurContext))
- AddObjCImplementationResults(getLangOptions(), Results, false);
+ AddObjCImplementationResults(getLangOpts(), Results, false);
else if (CurContext->isObjCContainer())
- AddObjCInterfaceResults(getLangOptions(), Results, false);
+ AddObjCInterfaceResults(getLangOpts(), Results, false);
else
AddObjCTopLevelResults(Results, false);
Results.ExitScope();
@@ -4367,8 +4367,8 @@
// @encode ( type-name )
const char *EncodeType = "char[]";
- if (Results.getSema().getLangOptions().CPlusPlus ||
- Results.getSema().getLangOptions().ConstStrings)
+ if (Results.getSema().getLangOpts().CPlusPlus ||
+ Results.getSema().getLangOpts().ConstStrings)
EncodeType = " const char[]";
Builder.AddResultTypeChunk(EncodeType);
Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
@@ -4474,7 +4474,7 @@
ResultBuilder Results(*this, CodeCompleter->getAllocator(),
CodeCompletionContext::CCC_Other);
Results.EnterNewScope();
- AddObjCVisibilityResults(getLangOptions(), Results, false);
+ AddObjCVisibilityResults(getLangOpts(), Results, false);
Results.ExitScope();
HandleCodeCompleteResults(this, CodeCompleter,
CodeCompletionContext::CCC_Other,
@@ -4708,9 +4708,8 @@
return;
// Add methods in protocols.
- const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
- for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
- E = Protocols.end();
+ for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
+ E = IFace->protocol_end();
I != E; ++I)
AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
CurContext, Selectors, AllowSameLength, Results, false);
@@ -5076,7 +5075,7 @@
typedef CodeCompletionResult Result;
ResultBuilder Results(*this, CodeCompleter->getAllocator(),
CodeCompletionContext::CCC_ObjCMessageReceiver,
- getLangOptions().CPlusPlus0x
+ getLangOpts().CPlusPlus0x
? &ResultBuilder::IsObjCMessageReceiverOrLambdaCapture
: &ResultBuilder::IsObjCMessageReceiver);
@@ -5095,7 +5094,7 @@
AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
}
- if (getLangOptions().CPlusPlus0x)
+ if (getLangOpts().CPlusPlus0x)
addThisCompletion(*this, Results);
Results.ExitScope();
@@ -6763,7 +6762,7 @@
// Add Key-Value-Coding and Key-Value-Observing accessor methods for all of
// the properties in this class and its categories.
- if (Context.getLangOptions().ObjC2) {
+ if (Context.getLangOpts().ObjC2) {
SmallVector<ObjCContainerDecl *, 4> Containers;
Containers.push_back(SearchDecl);
@@ -6975,7 +6974,7 @@
Builder.AddPlaceholderChunk("arguments");
Results.AddResult(Builder.TakeString());
- if (getLangOptions().ObjC1) {
+ if (getLangOpts().ObjC1) {
// #import "header"
Builder.AddTypedTextChunk("import");
Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
Modified: cfe/branches/tooling/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaDecl.cpp?rev=153047&r1=153046&r2=153047&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaDecl.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaDecl.cpp Mon Mar 19 14:02:20 2012
@@ -191,7 +191,7 @@
// Ignore a correction to a template type as the to-be-corrected
// identifier is not a template (typo correction for template names
// is handled elsewhere).
- !(getLangOptions().CPlusPlus && NewSSPtr &&
+ !(getLangOpts().CPlusPlus && NewSSPtr &&
isTemplateName(S, *NewSSPtr, false, TemplateName, ParsedType(),
false, Template, MemberOfUnknownSpecialization))) {
ParsedType Ty = getTypeName(*NewII, NameLoc, S, NewSSPtr,
@@ -199,9 +199,9 @@
IsCtorOrDtorName,
WantNontrivialTypeSourceInfo);
if (Ty) {
- std::string CorrectedStr(Correction.getAsString(getLangOptions()));
+ std::string CorrectedStr(Correction.getAsString(getLangOpts()));
std::string CorrectedQuotedStr(
- Correction.getQuoted(getLangOptions()));
+ Correction.getQuoted(getLangOpts()));
Diag(NameLoc, diag::err_unknown_typename_suggest)
<< Result.getLookupName() << CorrectedQuotedStr
<< FixItHint::CreateReplacement(SourceRange(NameLoc),
@@ -373,8 +373,8 @@
if (TypoCorrection Corrected = CorrectTypo(DeclarationNameInfo(&II, IILoc),
LookupOrdinaryName, S, SS,
Validator)) {
- std::string CorrectedStr(Corrected.getAsString(getLangOptions()));
- std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOptions()));
+ std::string CorrectedStr(Corrected.getAsString(getLangOpts()));
+ std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts()));
if (Corrected.isKeyword()) {
// We corrected to a keyword.
@@ -406,7 +406,7 @@
return true;
}
- if (getLangOptions().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
// See if II is a class template that the user forgot to pass arguments to.
UnqualifiedId Name;
Name.setIdentifier(&II, IILoc);
@@ -436,7 +436,7 @@
<< &II << DC << SS->getRange();
else if (isDependentScopeSpecifier(*SS)) {
unsigned DiagID = diag::err_typename_missing;
- if (getLangOptions().MicrosoftMode && isMicrosoftMissingTypename(SS, S))
+ if (getLangOpts().MicrosoftMode && isMicrosoftMissingTypename(SS, S))
DiagID = diag::warn_typename_missing;
Diag(SS->getRange().getBegin(), DiagID)
@@ -456,7 +456,7 @@
/// \brief Determine whether the given result set contains either a type name
/// or
static bool isResultTypeOrTemplate(LookupResult &R, const Token &NextToken) {
- bool CheckTemplate = R.getSema().getLangOptions().CPlusPlus &&
+ bool CheckTemplate = R.getSema().getLangOpts().CPlusPlus &&
NextToken.is(tok::less);
for (LookupResult::iterator I = R.begin(), IEnd = R.end(); I != IEnd; ++I) {
@@ -508,7 +508,7 @@
if (!SS.isSet() && NextToken.is(tok::l_paren)) {
// In C++, this is an ADL-only call.
// FIXME: Reference?
- if (getLangOptions().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
return BuildDeclarationNameExpr(SS, Result, /*ADL=*/true);
// C90 6.3.2.2:
@@ -533,7 +533,7 @@
// In C, we first see whether there is a tag type by the same name, in
// which case it's likely that the user just forget to write "enum",
// "struct", or "union".
- if (!getLangOptions().CPlusPlus && !SecondTry) {
+ if (!getLangOpts().CPlusPlus && !SecondTry) {
Result.clear(LookupTagName);
LookupParsedName(Result, S, &SS);
if (TagDecl *Tag = Result.getAsSingle<TagDecl>()) {
@@ -562,7 +562,7 @@
}
Diag(NameLoc, diag::err_use_of_tag_name_without_tag)
- << Name << TagName << getLangOptions().CPlusPlus
+ << Name << TagName << getLangOpts().CPlusPlus
<< FixItHint::CreateInsertion(NameLoc, FixItTagName);
break;
}
@@ -580,13 +580,13 @@
&SS, DefaultValidator)) {
unsigned UnqualifiedDiag = diag::err_undeclared_var_use_suggest;
unsigned QualifiedDiag = diag::err_no_member_suggest;
- std::string CorrectedStr(Corrected.getAsString(getLangOptions()));
- std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOptions()));
+ std::string CorrectedStr(Corrected.getAsString(getLangOpts()));
+ std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts()));
NamedDecl *FirstDecl = Corrected.getCorrectionDecl();
NamedDecl *UnderlyingFirstDecl
= FirstDecl? FirstDecl->getUnderlyingDecl() : 0;
- if (getLangOptions().CPlusPlus && NextToken.is(tok::less) &&
+ if (getLangOpts().CPlusPlus && NextToken.is(tok::less) &&
UnderlyingFirstDecl && isa<TemplateDecl>(UnderlyingFirstDecl)) {
UnqualifiedDiag = diag::err_no_template_suggest;
QualifiedDiag = diag::err_no_member_template_suggest;
@@ -668,7 +668,7 @@
break;
case LookupResult::Ambiguous:
- if (getLangOptions().CPlusPlus && NextToken.is(tok::less) &&
+ if (getLangOpts().CPlusPlus && NextToken.is(tok::less) &&
hasAnyAcceptableTemplateNames(Result)) {
// C++ [temp.local]p3:
// A lookup that finds an injected-class-name (10.2) can result in an
@@ -692,7 +692,7 @@
return NameClassification::Error();
}
- if (getLangOptions().CPlusPlus && NextToken.is(tok::less) &&
+ if (getLangOpts().CPlusPlus && NextToken.is(tok::less) &&
(IsFilteredTemplateName || hasAnyAcceptableTemplateNames(Result))) {
// C++ [temp.names]p3:
// After name lookup (3.4) finds that a name is a template-name or that
@@ -895,7 +895,7 @@
/// attribute.
static bool AllowOverloadingOfFunction(LookupResult &Previous,
ASTContext &Context) {
- if (Context.getLangOptions().CPlusPlus)
+ if (Context.getLangOpts().CPlusPlus)
return true;
if (Previous.getResultKind() == LookupResult::FoundOverloaded)
@@ -922,7 +922,7 @@
// Out-of-line definitions shouldn't be pushed into scope in C++.
// Out-of-line variable and function definitions shouldn't even in C.
- if ((getLangOptions().CPlusPlus || isa<VarDecl>(D) || isa<FunctionDecl>(D)) &&
+ if ((getLangOpts().CPlusPlus || isa<VarDecl>(D) || isa<FunctionDecl>(D)) &&
D->isOutOfLine() &&
!D->getDeclContext()->getRedeclContext()->Equals(
D->getLexicalDeclContext()->getRedeclContext()))
@@ -1184,7 +1184,7 @@
FixItHint &Hint) {
if (isa<LabelDecl>(D)) {
SourceLocation AfterColon = Lexer::findLocationAfterToken(D->getLocEnd(),
- tok::colon, Ctx.getSourceManager(), Ctx.getLangOptions(), true);
+ tok::colon, Ctx.getSourceManager(), Ctx.getLangOpts(), true);
if (AfterColon.isInvalid())
return;
Hint = FixItHint::CreateRemoval(CharSourceRange::
@@ -1329,7 +1329,7 @@
while (((S->getFlags() & Scope::DeclScope) == 0) ||
(S->getEntity() &&
((DeclContext *)S->getEntity())->isTransparentContext()) ||
- (S->isClassScope() && !getLangOptions().CPlusPlus))
+ (S->isClassScope() && !getLangOpts().CPlusPlus))
S = S->getParent();
return S;
}
@@ -1464,7 +1464,7 @@
// Allow multiple definitions for ObjC built-in typedefs.
// FIXME: Verify the underlying types are equivalent!
- if (getLangOptions().ObjC1) {
+ if (getLangOpts().ObjC1) {
const IdentifierInfo *TypeID = New->getIdentifier();
switch (TypeID->getLength()) {
default: break;
@@ -1520,10 +1520,10 @@
if (TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Old))
New->setPreviousDeclaration(Typedef);
- if (getLangOptions().MicrosoftExt)
+ if (getLangOpts().MicrosoftExt)
return;
- if (getLangOptions().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
// C++ [dcl.typedef]p2:
// In a given non-class scope, a typedef specifier can be used to
// redefine the name of any type declared in that scope to refer
@@ -1562,7 +1562,7 @@
}
// Modules always permit redefinition of typedefs, as does C11.
- if (getLangOptions().Modules || getLangOptions().C11)
+ if (getLangOpts().Modules || getLangOpts().C11)
return;
// If we have a redefinition of a typedef in C, emit a warning. This warning
@@ -1720,7 +1720,7 @@
/// merged with.
///
/// Returns true if there was an error, false otherwise.
-bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
+bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) {
// Verify the old decl was also a function.
FunctionDecl *Old = 0;
if (FunctionTemplateDecl *OldFunctionTemplate
@@ -1762,8 +1762,8 @@
if (!isa<CXXMethodDecl>(New) && !isa<CXXMethodDecl>(Old) &&
New->getStorageClass() == SC_Static &&
Old->getStorageClass() != SC_Static &&
- !canRedefineFunction(Old, getLangOptions())) {
- if (getLangOptions().MicrosoftExt) {
+ !canRedefineFunction(Old, getLangOpts())) {
+ if (getLangOpts().MicrosoftExt) {
Diag(New->getLocation(), diag::warn_static_non_static) << New;
Diag(Old->getLocation(), PrevDiag);
} else {
@@ -1845,7 +1845,7 @@
NewQType = Context.getCanonicalType(New->getType());
}
- if (getLangOptions().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
// (C++98 13.1p2):
// Certain function declarations cannot be overloaded:
// -- Function declarations that differ only in the return type
@@ -1950,14 +1950,14 @@
}
if (OldQTypeForComparison == NewQType)
- return MergeCompatibleFunctionDecls(New, Old);
+ return MergeCompatibleFunctionDecls(New, Old, S);
// Fall through for conflicting redeclarations and redefinitions.
}
// 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 &&
+ if (!getLangOpts().CPlusPlus &&
Context.typesAreCompatible(OldQType, NewQType)) {
const FunctionType *OldFuncType = OldQType->getAs<FunctionType>();
const FunctionType *NewFuncType = NewQType->getAs<FunctionType>();
@@ -1995,7 +1995,7 @@
New->setParams(Params);
}
- return MergeCompatibleFunctionDecls(New, Old);
+ return MergeCompatibleFunctionDecls(New, Old, S);
}
// GNU C permits a K&R definition to follow a prototype declaration
@@ -2009,7 +2009,7 @@
// the K&R definition becomes variadic. This is sort of an edge case, but
// it's legal per the standard depending on how you read C99 6.7.5.3p15 and
// C99 6.9.1p8.
- if (!getLangOptions().CPlusPlus &&
+ if (!getLangOpts().CPlusPlus &&
Old->hasPrototype() && !New->hasPrototype() &&
New->getType()->getAs<FunctionProtoType>() &&
Old->getNumParams() == New->getNumParams()) {
@@ -2056,7 +2056,7 @@
New->setType(Context.getFunctionType(MergedReturn, &ArgTypes[0],
ArgTypes.size(),
OldProto->getExtProtoInfo()));
- return MergeCompatibleFunctionDecls(New, Old);
+ return MergeCompatibleFunctionDecls(New, Old, S);
}
// Fall through to diagnose conflicting types.
@@ -2097,7 +2097,8 @@
/// redeclaration of Old.
///
/// \returns false
-bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old) {
+bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old,
+ Scope *S) {
// Merge the attributes
mergeDeclAttributes(New, Old);
@@ -2117,8 +2118,8 @@
mergeParamDeclAttributes(New->getParamDecl(i), Old->getParamDecl(i),
Context);
- if (getLangOptions().CPlusPlus)
- return MergeCXXFunctionDecl(New, Old);
+ if (getLangOpts().CPlusPlus)
+ return MergeCXXFunctionDecl(New, Old, S);
return false;
}
@@ -2155,7 +2156,7 @@
return;
QualType MergedT;
- if (getLangOptions().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
AutoType *AT = New->getType()->getContainedAutoType();
if (AT && !AT->isDeduced()) {
// We don't know what the new type is until the initializer is attached.
@@ -2316,7 +2317,7 @@
// C++ doesn't have tentative definitions, so go right ahead and check here.
const VarDecl *Def;
- if (getLangOptions().CPlusPlus &&
+ if (getLangOpts().CPlusPlus &&
New->isThisDeclarationADefinition() == VarDecl::Definition &&
(Def = Old->getDefinition())) {
Diag(New->getLocation(), diag::err_redefinition)
@@ -2378,8 +2379,11 @@
Tag = CTD->getTemplatedDecl();
}
- if (Tag)
+ if (Tag) {
Tag->setFreeStanding();
+ if (Tag->isInvalidDecl())
+ return Tag;
+ }
if (unsigned TypeQuals = DS.getTypeQualifiers()) {
// Enforce C99 6.7.3p2: "Types other than pointer types derived from object
@@ -2419,18 +2423,18 @@
if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Tag)) {
if (!Record->getDeclName() && Record->isCompleteDefinition() &&
DS.getStorageClassSpec() != DeclSpec::SCS_typedef) {
- if (getLangOptions().CPlusPlus ||
+ if (getLangOpts().CPlusPlus ||
Record->getDeclContext()->isRecord())
return BuildAnonymousStructOrUnion(S, DS, AS, Record);
- Diag(DS.getSourceRange().getBegin(), diag::ext_no_declarators)
+ Diag(DS.getLocStart(), diag::ext_no_declarators)
<< DS.getSourceRange();
emittedWarning = true;
}
}
// Check for Microsoft C extension: anonymous struct.
- if (getLangOptions().MicrosoftExt && !getLangOptions().CPlusPlus &&
+ if (getLangOpts().MicrosoftExt && !getLangOpts().CPlusPlus &&
CurContext->isRecord() &&
DS.getStorageClassSpec() == DeclSpec::SCS_unspecified) {
// Handle 2 kinds of anonymous struct:
@@ -2441,13 +2445,13 @@
if ((Record && Record->getDeclName() && !Record->isCompleteDefinition()) ||
(DS.getTypeSpecType() == DeclSpec::TST_typename &&
DS.getRepAsType().get()->isStructureType())) {
- Diag(DS.getSourceRange().getBegin(), diag::ext_ms_anonymous_struct)
+ Diag(DS.getLocStart(), diag::ext_ms_anonymous_struct)
<< DS.getSourceRange();
return BuildMicrosoftCAnonymousStruct(S, DS, Record);
}
}
- if (getLangOptions().CPlusPlus &&
+ if (getLangOpts().CPlusPlus &&
DS.getStorageClassSpec() != DeclSpec::SCS_typedef)
if (EnumDecl *Enum = dyn_cast_or_null<EnumDecl>(Tag))
if (Enum->enumerator_begin() == Enum->enumerator_end() &&
@@ -2465,12 +2469,12 @@
// extension in both Microsoft and GNU.
if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef &&
Tag && isa<EnumDecl>(Tag)) {
- Diag(DS.getSourceRange().getBegin(), diag::ext_typedef_without_a_name)
+ Diag(DS.getLocStart(), diag::ext_typedef_without_a_name)
<< DS.getSourceRange();
return Tag;
}
- Diag(DS.getSourceRange().getBegin(), diag::ext_no_declarators)
+ Diag(DS.getLocStart(), diag::ext_no_declarators)
<< DS.getSourceRange();
emittedWarning = true;
}
@@ -2696,17 +2700,17 @@
DeclContext *Owner = Record->getDeclContext();
// Diagnose whether this anonymous struct/union is an extension.
- if (Record->isUnion() && !getLangOptions().CPlusPlus && !getLangOptions().C11)
+ if (Record->isUnion() && !getLangOpts().CPlusPlus && !getLangOpts().C11)
Diag(Record->getLocation(), diag::ext_anonymous_union);
- else if (!Record->isUnion() && getLangOptions().CPlusPlus)
+ else if (!Record->isUnion() && getLangOpts().CPlusPlus)
Diag(Record->getLocation(), diag::ext_gnu_anonymous_struct);
- else if (!Record->isUnion() && !getLangOptions().C11)
+ else if (!Record->isUnion() && !getLangOpts().C11)
Diag(Record->getLocation(), diag::ext_c11_anonymous_struct);
// C and C++ require different kinds of checks for anonymous
// structs/unions.
bool Invalid = false;
- if (getLangOptions().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
const char* PrevSpec = 0;
unsigned DiagID;
if (Record->isUnion()) {
@@ -2796,7 +2800,7 @@
if (!MemRecord->isAnonymousStructOrUnion() &&
MemRecord->getDeclName()) {
// Visual C++ allows type definition in anonymous struct or union.
- if (getLangOptions().MicrosoftExt)
+ if (getLangOpts().MicrosoftExt)
Diag(MemRecord->getLocation(), diag::ext_anonymous_record_with_type)
<< (int)Record->isUnion();
else {
@@ -2820,7 +2824,7 @@
DK = diag::err_anonymous_record_with_static;
// Visual C++ allows type definition in anonymous struct or union.
- if (getLangOptions().MicrosoftExt &&
+ if (getLangOpts().MicrosoftExt &&
DK == diag::err_anonymous_record_with_type)
Diag((*Mem)->getLocation(), diag::ext_anonymous_record_with_type)
<< (int)Record->isUnion();
@@ -2835,7 +2839,7 @@
if (!Record->isUnion() && !Owner->isRecord()) {
Diag(Record->getLocation(), diag::err_anonymous_struct_not_member)
- << (int)getLangOptions().CPlusPlus;
+ << (int)getLangOpts().CPlusPlus;
Invalid = true;
}
@@ -2848,7 +2852,7 @@
NamedDecl *Anon = 0;
if (RecordDecl *OwningClass = dyn_cast<RecordDecl>(Owner)) {
Anon = FieldDecl::Create(Context, OwningClass,
- DS.getSourceRange().getBegin(),
+ DS.getLocStart(),
Record->getLocation(),
/*IdentifierInfo=*/0,
Context.getTypeDeclType(Record),
@@ -2856,7 +2860,7 @@
/*BitWidth=*/0, /*Mutable=*/false,
/*HasInit=*/false);
Anon->setAccess(AS);
- if (getLangOptions().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
FieldCollector->Add(cast<FieldDecl>(Anon));
} else {
DeclSpec::SCS SCSpec = DS.getStorageClassSpec();
@@ -2875,7 +2879,7 @@
= StorageClassSpecToVarDeclStorageClass(SCSpec);
Anon = VarDecl::Create(Context, Owner,
- DS.getSourceRange().getBegin(),
+ DS.getLocStart(),
Record->getLocation(), /*IdentifierInfo=*/0,
Context.getTypeDeclType(Record),
TInfo, SC, SCAsWritten);
@@ -2945,8 +2949,8 @@
// Create a declaration for this anonymous struct.
NamedDecl* Anon = FieldDecl::Create(Context,
cast<RecordDecl>(CurContext),
- DS.getSourceRange().getBegin(),
- DS.getSourceRange().getBegin(),
+ DS.getLocStart(),
+ DS.getLocStart(),
/*IdentifierInfo=*/0,
Context.getTypeDeclType(Record),
TInfo,
@@ -3231,7 +3235,44 @@
return false;
}
+
+/// \brief Diagnose a declaration that has a qualified name within a class,
+/// which is ill-formed but often recoverable.
+///
+/// \returns true if we cannot safely recover from this error, false otherwise.
+bool Sema::diagnoseQualifiedDeclInClass(CXXScopeSpec &SS, DeclContext *DC,
+ DeclarationName Name,
+ SourceLocation Loc) {
+ // The user provided a superfluous scope specifier inside a class
+ // definition:
+ //
+ // class X {
+ // void X::f();
+ // };
+ if (CurContext->Equals(DC)) {
+ Diag(Loc, diag::warn_member_extra_qualification)
+ << Name << FixItHint::CreateRemoval(SS.getRange());
+ SS.clear();
+ return false;
+ }
+
+ Diag(Loc, diag::err_member_qualification)
+ << Name << SS.getRange();
+ SS.clear();
+
+ // C++ constructors and destructors with incorrect scopes can break
+ // our AST invariants by having the wrong underlying types. If
+ // that's the case, then drop this declaration entirely.
+ if ((Name.getNameKind() == DeclarationName::CXXConstructorName ||
+ Name.getNameKind() == DeclarationName::CXXDestructorName) &&
+ !Context.hasSameType(Name.getCXXNameType(),
+ Context.getTypeDeclType(
+ cast<CXXRecordDecl>(CurContext))))
+ return true;
+ return false;
+}
+
Decl *Sema::HandleDeclarator(Scope *S, Declarator &D,
MultiTemplateParamsArg TemplateParamLists) {
// TODO: consider using NameInfo for diagnostic.
@@ -3242,7 +3283,7 @@
// one, the ParsedFreeStandingDeclSpec action should be used.
if (!Name) {
if (!D.isInvalidType()) // Reject this if we think it is valid.
- Diag(D.getDeclSpec().getSourceRange().getBegin(),
+ Diag(D.getDeclSpec().getLocStart(),
diag::err_declarator_need_ident)
<< D.getDeclSpec().getSourceRange() << D.getSourceRange();
return 0;
@@ -3290,31 +3331,9 @@
D.setInvalidType();
} else if (isa<CXXRecordDecl>(CurContext) &&
!D.getDeclSpec().isFriendSpecified()) {
- // The user provided a superfluous scope specifier inside a class
- // definition:
- //
- // class X {
- // void X::f();
- // };
- if (CurContext->Equals(DC)) {
- Diag(D.getIdentifierLoc(), diag::warn_member_extra_qualification)
- << Name << FixItHint::CreateRemoval(D.getCXXScopeSpec().getRange());
- } else {
- Diag(D.getIdentifierLoc(), diag::err_member_qualification)
- << Name << D.getCXXScopeSpec().getRange();
-
- // C++ constructors and destructors with incorrect scopes can break
- // our AST invariants by having the wrong underlying types. If
- // that's the case, then drop this declaration entirely.
- if ((Name.getNameKind() == DeclarationName::CXXConstructorName ||
- Name.getNameKind() == DeclarationName::CXXDestructorName) &&
- !Context.hasSameType(Name.getCXXNameType(),
- Context.getTypeDeclType(cast<CXXRecordDecl>(CurContext))))
- return 0;
- }
-
- // Pretend that this qualifier was not here.
- D.getCXXScopeSpec().clear();
+ if (diagnoseQualifiedDeclInClass(D.getCXXScopeSpec(), DC,
+ Name, D.getIdentifierLoc()))
+ return 0;
}
}
@@ -3642,7 +3661,7 @@
Previous.clear();
}
- if (getLangOptions().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
// Check that there are no default arguments (C++ only).
CheckExtraCXXDefaultArguments(D);
}
@@ -3772,7 +3791,7 @@
if (!PrevDecl->hasLinkage())
return false;
- if (Context.getLangOptions().CPlusPlus) {
+ if (Context.getLangOpts().CPlusPlus) {
// C++ [basic.link]p6:
// If there is a visible declaration of an entity with linkage
// having the same name and type, ignoring entities declared
@@ -3861,7 +3880,7 @@
DeclarationName Name = GetNameForDeclarator(D).getName();
// Check that there are no default arguments (C++ only).
- if (getLangOptions().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
CheckExtraCXXDefaultArguments(D);
DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpec();
@@ -3903,7 +3922,7 @@
}
}
- if (getLangOptions().OpenCL) {
+ if (getLangOpts().OpenCL) {
// Set up the special work-group-local storage class for variables in the
// OpenCL __local address space.
if (R.getAddressSpace() == LangAS::opencl_local)
@@ -3912,8 +3931,8 @@
bool isExplicitSpecialization = false;
VarDecl *NewVD;
- if (!getLangOptions().CPlusPlus) {
- NewVD = VarDecl::Create(Context, DC, D.getSourceRange().getBegin(),
+ if (!getLangOpts().CPlusPlus) {
+ NewVD = VarDecl::Create(Context, DC, D.getLocStart(),
D.getIdentifierLoc(), II,
R, TInfo, SC, SCAsWritten);
@@ -3940,7 +3959,7 @@
// the program is ill-formed. C++11 drops this restriction.
if (RD->isUnion())
Diag(D.getIdentifierLoc(),
- getLangOptions().CPlusPlus0x
+ getLangOpts().CPlusPlus0x
? diag::warn_cxx98_compat_static_data_member_in_union
: diag::ext_static_data_member_in_union) << Name;
// We conservatively disallow static data members in anonymous structs.
@@ -3957,7 +3976,7 @@
bool Invalid = false;
if (TemplateParameterList *TemplateParams
= MatchTemplateParametersToScopeSpecifier(
- D.getDeclSpec().getSourceRange().getBegin(),
+ D.getDeclSpec().getLocStart(),
D.getIdentifierLoc(),
D.getCXXScopeSpec(),
TemplateParamLists.get(),
@@ -3983,7 +4002,7 @@
}
}
- NewVD = VarDecl::Create(Context, DC, D.getSourceRange().getBegin(),
+ NewVD = VarDecl::Create(Context, DC, D.getLocStart(),
D.getIdentifierLoc(), II,
R, TInfo, SC, SCAsWritten);
@@ -4040,7 +4059,7 @@
// In auto-retain/release, infer strong retension for variables of
// retainable type.
- if (getLangOptions().ObjCAutoRefCount && inferObjCARCLifetime(NewVD))
+ if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(NewVD))
NewVD->setInvalidDecl();
// Handle GNU asm-label extension (encoded as an attribute).
@@ -4087,7 +4106,7 @@
FilterLookupForScope(Previous, DC, S, NewVD->hasLinkage(),
isExplicitSpecialization);
- if (!getLangOptions().CPlusPlus) {
+ if (!getLangOpts().CPlusPlus) {
D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous));
} else {
// Merge the decl with the existing one if appropriate.
@@ -4280,7 +4299,7 @@
if (NewVD->hasLocalStorage() && T.isObjCGCWeak()
&& !NewVD->hasAttr<BlocksAttr>()) {
- if (getLangOptions().getGC() != LangOptions::NonGC)
+ if (getLangOpts().getGC() != LangOptions::NonGC)
Diag(NewVD->getLocation(), diag::warn_gc_attribute_weak_on_local);
else
Diag(NewVD->getLocation(), diag::warn_attribute_weak_on_local);
@@ -4499,7 +4518,7 @@
llvm::SmallVector<unsigned, 1> MismatchedParams;
llvm::SmallVector<std::pair<FunctionDecl*, unsigned>, 1> NearMatches;
TypoCorrection Correction;
- bool isFriendDecl = (SemaRef.getLangOptions().CPlusPlus &&
+ bool isFriendDecl = (SemaRef.getLangOpts().CPlusPlus &&
ExtraArgs.D.getDeclSpec().isFriendSpecified());
unsigned DiagMsg = isFriendDecl ? diag::err_no_matching_local_friend
: diag::err_member_def_does_not_match;
@@ -4581,10 +4600,10 @@
if (Correction)
SemaRef.Diag(NewFD->getLocation(), DiagMsg)
- << Name << NewDC << Correction.getQuoted(SemaRef.getLangOptions())
+ << Name << NewDC << Correction.getQuoted(SemaRef.getLangOpts())
<< FixItHint::CreateReplacement(
NewFD->getLocation(),
- Correction.getAsString(SemaRef.getLangOptions()));
+ Correction.getAsString(SemaRef.getLangOpts()));
else
SemaRef.Diag(NewFD->getLocation(), DiagMsg)
<< Name << NewDC << NewFD->getLocation();
@@ -4608,7 +4627,7 @@
<< Idx << FDParam->getType() << NewFD->getParamDecl(Idx-1)->getType();
} else if (Correction) {
SemaRef.Diag(FD->getLocation(), diag::note_previous_decl)
- << Correction.getQuoted(SemaRef.getLangOptions());
+ << Correction.getQuoted(SemaRef.getLangOpts());
} else if (FDisConst != NewFDisConst) {
SemaRef.Diag(FD->getLocation(), diag::note_member_def_close_const_match)
<< NewFDisConst << FD->getSourceRange().getEnd();
@@ -4665,7 +4684,7 @@
FunctionDecl::StorageClass SCAsWritten
= StorageClassSpecToFunctionDeclStorageClass(SCSpec);
- if (!SemaRef.getLangOptions().CPlusPlus) {
+ if (!SemaRef.getLangOpts().CPlusPlus) {
// Determine whether the function was written with a
// prototype. This true when:
// - there is a prototype in the declarator, or
@@ -4676,7 +4695,7 @@
(!isa<FunctionType>(R.getTypePtr()) && R->isFunctionProtoType());
NewFD = FunctionDecl::Create(SemaRef.Context, DC,
- D.getSourceRange().getBegin(), NameInfo, R,
+ D.getLocStart(), NameInfo, R,
TInfo, SC, SCAsWritten, isInline,
HasPrototype);
if (D.isInvalidType())
@@ -4708,7 +4727,7 @@
R = SemaRef.CheckConstructorDeclarator(D, R, SC);
return CXXConstructorDecl::Create(SemaRef.Context, cast<CXXRecordDecl>(DC),
- D.getSourceRange().getBegin(), NameInfo,
+ D.getLocStart(), NameInfo,
R, TInfo, isExplicit, isInline,
/*isImplicitlyDeclared=*/false,
isConstexpr);
@@ -4720,14 +4739,14 @@
CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
CXXDestructorDecl *NewDD = CXXDestructorDecl::Create(
SemaRef.Context, Record,
- D.getSourceRange().getBegin(),
+ D.getLocStart(),
NameInfo, R, TInfo, isInline,
/*isImplicitlyDeclared=*/false);
// If the class is complete, then we now create the implicit exception
// specification. If the class is incomplete or dependent, we can't do
// it yet.
- if (SemaRef.getLangOptions().CPlusPlus0x && !Record->isDependentType() &&
+ if (SemaRef.getLangOpts().CPlusPlus0x && !Record->isDependentType() &&
Record->getDefinition() && !Record->isBeingDefined() &&
R->getAs<FunctionProtoType>()->getExceptionSpecType() == EST_None) {
SemaRef.AdjustDestructorExceptionSpec(Record, NewDD);
@@ -4743,7 +4762,7 @@
// Create a FunctionDecl to satisfy the function definition parsing
// code path.
return FunctionDecl::Create(SemaRef.Context, DC,
- D.getSourceRange().getBegin(),
+ D.getLocStart(),
D.getIdentifierLoc(), Name, R, TInfo,
SC, SCAsWritten, isInline,
/*hasPrototype=*/true, isConstexpr);
@@ -4759,7 +4778,7 @@
SemaRef.CheckConversionDeclarator(D, R, SC);
IsVirtualOkay = true;
return CXXConversionDecl::Create(SemaRef.Context, cast<CXXRecordDecl>(DC),
- D.getSourceRange().getBegin(), NameInfo,
+ D.getLocStart(), NameInfo,
R, TInfo, isInline, isExplicit,
isConstexpr, SourceLocation());
@@ -4795,7 +4814,7 @@
// This is a C++ method declaration.
return CXXMethodDecl::Create(SemaRef.Context, cast<CXXRecordDecl>(DC),
- D.getSourceRange().getBegin(), NameInfo, R,
+ D.getLocStart(), NameInfo, R,
TInfo, isStatic, SCAsWritten, isInline,
isConstexpr, SourceLocation());
@@ -4804,7 +4823,7 @@
// prototype. This true when:
// - we're in C++ (where every function has a prototype),
return FunctionDecl::Create(SemaRef.Context, DC,
- D.getSourceRange().getBegin(),
+ D.getLocStart(),
NameInfo, R, TInfo, SC, SCAsWritten, isInline,
true/*HasPrototype*/, isConstexpr);
}
@@ -4859,7 +4878,7 @@
if (OriginalLexicalContext && OriginalLexicalContext->isObjCContainer())
NewFD->setTopLevelDeclInObjCContainer();
- if (getLangOptions().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
bool isInline = D.getDeclSpec().isInlineSpecified();
bool isVirtual = D.getDeclSpec().isVirtualSpecified();
bool isExplicit = D.getDeclSpec().isExplicitSpecified();
@@ -4888,7 +4907,7 @@
bool Invalid = false;
if (TemplateParameterList *TemplateParams
= MatchTemplateParametersToScopeSpecifier(
- D.getDeclSpec().getSourceRange().getBegin(),
+ D.getDeclSpec().getLocStart(),
D.getIdentifierLoc(),
D.getCXXScopeSpec(),
TemplateParamLists.get(),
@@ -5201,7 +5220,7 @@
// In C++, the empty parameter-type-list must be spelled "void"; a
// typedef of void is not permitted.
- if (getLangOptions().CPlusPlus &&
+ if (getLangOpts().CPlusPlus &&
Param->getType().getUnqualifiedType() != Context.VoidTy) {
bool IsTypeAlias = false;
if (const TypedefType *TT = Param->getType()->getAs<TypedefType>())
@@ -5263,21 +5282,22 @@
ProcessDeclAttributes(S, NewFD, D,
/*NonInheritable=*/true, /*Inheritable=*/false);
- if (!getLangOptions().CPlusPlus) {
+ // Functions returning a variably modified type violate C99 6.7.5.2p2
+ // because all functions have linkage.
+ if (!NewFD->isInvalidDecl() &&
+ NewFD->getResultType()->isVariablyModifiedType()) {
+ Diag(NewFD->getLocation(), diag::err_vm_func_decl);
+ NewFD->setInvalidDecl();
+ }
+
+ if (!getLangOpts().CPlusPlus) {
// Perform semantic checking on the function declaration.
bool isExplicitSpecialization=false;
if (!NewFD->isInvalidDecl()) {
- if (NewFD->getResultType()->isVariablyModifiedType()) {
- // Functions returning a variably modified type violate C99 6.7.5.2p2
- // because all functions have linkage.
- Diag(NewFD->getLocation(), diag::err_vm_func_decl);
- NewFD->setInvalidDecl();
- } else {
- if (NewFD->isMain())
- CheckMain(NewFD, D.getDeclSpec());
- D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous,
- isExplicitSpecialization));
- }
+ if (NewFD->isMain())
+ CheckMain(NewFD, D.getDeclSpec());
+ D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous,
+ isExplicitSpecialization));
}
assert((NewFD->isInvalidDecl() || !D.isRedeclaration() ||
Previous.getResultKind() != LookupResult::FoundOverloaded) &&
@@ -5317,7 +5337,7 @@
Diag(D.getIdentifierLoc(), diag::err_template_spec_needs_header)
<< SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)
<< FixItHint::CreateInsertion(
- D.getDeclSpec().getSourceRange().getBegin(),
+ D.getDeclSpec().getLocStart(),
"template<> ");
isFunctionTemplateSpecialization = true;
} else {
@@ -5355,7 +5375,7 @@
if (CurContext->isDependentContext() && CurContext->isRecord()
&& !isFriend) {
isDependentClassScopeExplicitSpecialization = true;
- Diag(NewFD->getLocation(), getLangOptions().MicrosoftExt ?
+ Diag(NewFD->getLocation(), getLangOpts().MicrosoftExt ?
diag::ext_function_specialization_in_class :
diag::err_function_specialization_in_class)
<< NewFD->getDeclName();
@@ -5573,7 +5593,7 @@
// Set this FunctionDecl's range up to the right paren.
NewFD->setRangeEnd(D.getSourceRange().getEnd());
- if (getLangOptions().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
if (FunctionTemplate) {
if (NewFD->isInvalidDecl())
FunctionTemplate->setInvalidDecl();
@@ -5583,7 +5603,7 @@
MarkUnusedFileScopedDecl(NewFD);
- if (getLangOptions().CUDA)
+ if (getLangOpts().CUDA)
if (IdentifierInfo *II = NewFD->getIdentifier())
if (!NewFD->isInvalidDecl() &&
NewFD->getDeclContext()->getRedeclContext()->isTranslationUnit()) {
@@ -5673,7 +5693,7 @@
break;
}
- if (!getLangOptions().CPlusPlus && !NewFD->hasAttr<OverloadableAttr>()) {
+ if (!getLangOpts().CPlusPlus && !NewFD->hasAttr<OverloadableAttr>()) {
// If a function name is overloadable in C, then every function
// with that name must be marked "overloadable".
Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing)
@@ -5694,7 +5714,7 @@
if (Redeclaration) {
// NewFD and OldDecl represent declarations that need to be
// merged.
- if (MergeFunctionDecl(NewFD, OldDecl)) {
+ if (MergeFunctionDecl(NewFD, OldDecl, S)) {
NewFD->setInvalidDecl();
return Redeclaration;
}
@@ -5731,7 +5751,7 @@
}
// Semantic checking for this function declaration (in isolation).
- if (getLangOptions().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
// C++-specific checks.
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(NewFD)) {
CheckConstructor(Constructor);
@@ -5832,7 +5852,7 @@
// shall not appear in a declaration of main.
// static main is not an error under C99, but we should warn about it.
if (FD->getStorageClass() == SC_Static)
- Diag(DS.getStorageClassSpecLoc(), getLangOptions().CPlusPlus
+ Diag(DS.getStorageClassSpecLoc(), getLangOpts().CPlusPlus
? diag::err_static_main : diag::warn_static_main)
<< FixItHint::CreateRemoval(DS.getStorageClassSpecLoc());
if (FD->isInlineSpecified())
@@ -5858,7 +5878,7 @@
// In C with GNU extensions we allow main() to have non-integer return
// type, but we should warn about the extension, and we disable the
// implicit-return-zero rule.
- } else if (getLangOptions().GNUMode && !getLangOptions().CPlusPlus) {
+ } else if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) {
Diag(FD->getTypeSpecStartLoc(), diag::ext_main_returns_nonint);
// Otherwise, this is just a flat-out error.
@@ -6093,14 +6113,14 @@
if (CXXDirectInit->getNumExprs() == 0) {
// It isn't possible to write this directly, but it is possible to
// end up in this situation with "auto x(some_pack...);"
- Diag(CXXDirectInit->getSourceRange().getBegin(),
+ Diag(CXXDirectInit->getLocStart(),
diag::err_auto_var_init_no_expression)
<< VDecl->getDeclName() << VDecl->getType()
<< VDecl->getSourceRange();
RealDecl->setInvalidDecl();
return;
} else if (CXXDirectInit->getNumExprs() > 1) {
- Diag(CXXDirectInit->getExpr(1)->getSourceRange().getBegin(),
+ Diag(CXXDirectInit->getExpr(1)->getLocStart(),
diag::err_auto_var_init_multiple_expressions)
<< VDecl->getDeclName() << VDecl->getType()
<< VDecl->getSourceRange();
@@ -6123,7 +6143,7 @@
VDecl->ClearLinkageCache();
// In ARC, infer lifetime.
- if (getLangOptions().ObjCAutoRefCount && inferObjCARCLifetime(VDecl))
+ if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(VDecl))
VDecl->setInvalidDecl();
// If this is a redeclaration, check that the type we just deduced matches
@@ -6169,7 +6189,7 @@
}
const VarDecl* PrevInit = 0;
- if (getLangOptions().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
// C++ [class.static.data]p4
// If a static data member is of const integral or const
// enumeration type, its declaration in the class definition can
@@ -6209,6 +6229,18 @@
// Get the decls type and save a reference for later, since
// CheckInitializerTypes may change it.
QualType DclT = VDecl->getType(), SavT = DclT;
+
+ // Top-level message sends default to 'id' when we're in a debugger
+ // and we are assigning it to a variable of 'id' type.
+ if (getLangOpts().DebuggerCastResultToId && DclT->isObjCIdType())
+ if (Init->getType() == Context.UnknownAnyTy && isa<ObjCMessageExpr>(Init)) {
+ ExprResult Result = forceUnknownAnyToType(Init, Context.getObjCIdType());
+ if (Result.isInvalid()) {
+ VDecl->setInvalidDecl();
+ return;
+ }
+ Init = Result.take();
+ }
// Perform the initialization.
if (!VDecl->isInvalidDecl()) {
@@ -6262,7 +6294,7 @@
// C99 6.7.8p4: All the expressions in an initializer for an object that has
// static storage duration shall be constant expressions or string literals.
// C++ does not have this restriction.
- if (!getLangOptions().CPlusPlus && !VDecl->isInvalidDecl() &&
+ if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl() &&
VDecl->getStorageClass() == SC_Static)
CheckForConstantInitializer(Init, DclT);
} else if (VDecl->isStaticDataMember() &&
@@ -6306,7 +6338,7 @@
} else if (DclT->isIntegralOrEnumerationType()) {
// Check whether the expression is a constant expression.
SourceLocation Loc;
- if (getLangOptions().CPlusPlus0x && DclT.isVolatileQualified())
+ if (getLangOpts().CPlusPlus0x && DclT.isVolatileQualified())
// In C++11, a non-constexpr const static data member with an
// in-class initializer cannot be volatile.
Diag(VDecl->getLocation(), diag::err_in_class_initializer_volatile);
@@ -6331,7 +6363,7 @@
} else if (DclT->isFloatingType()) { // also permits complex, which is ok
Diag(VDecl->getLocation(), diag::ext_in_class_initializer_float_type)
<< DclT << Init->getSourceRange();
- if (getLangOptions().CPlusPlus0x)
+ if (getLangOpts().CPlusPlus0x)
Diag(VDecl->getLocation(),
diag::note_in_class_initializer_float_type_constexpr)
<< FixItHint::CreateInsertion(VDecl->getLocStart(), "constexpr ");
@@ -6343,7 +6375,7 @@
}
// Suggest adding 'constexpr' in C++11 for literal types.
- } else if (getLangOptions().CPlusPlus0x && DclT->isLiteralType()) {
+ } else if (getLangOpts().CPlusPlus0x && DclT->isLiteralType()) {
Diag(VDecl->getLocation(), diag::err_in_class_initializer_literal_type)
<< DclT << Init->getSourceRange()
<< FixItHint::CreateInsertion(VDecl->getLocStart(), "constexpr ");
@@ -6356,12 +6388,12 @@
}
} else if (VDecl->isFileVarDecl()) {
if (VDecl->getStorageClassAsWritten() == SC_Extern &&
- (!getLangOptions().CPlusPlus ||
+ (!getLangOpts().CPlusPlus ||
!Context.getBaseElementType(VDecl->getType()).isConstQualified()))
Diag(VDecl->getLocation(), diag::warn_extern_init);
// C99 6.7.8p4. All file scoped initializers need to be constant.
- if (!getLangOptions().CPlusPlus && !VDecl->isInvalidDecl())
+ if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl())
CheckForConstantInitializer(Init, DclT);
}
@@ -6582,7 +6614,7 @@
// trivial default constructor and a trivial destructor, a cv-qualified
// version of one of these types, or an array of one of the preceding
// types and is declared without an initializer.
- if (getLangOptions().CPlusPlus && Var->hasLocalStorage()) {
+ if (getLangOpts().CPlusPlus && Var->hasLocalStorage()) {
if (const RecordType *Record
= Context.getBaseElementType(Type)->getAs<RecordType>()) {
CXXRecordDecl *CXXRecord = cast<CXXRecordDecl>(Record->getDecl());
@@ -6674,7 +6706,7 @@
// In ARC, don't allow jumps past the implicit initialization of a
// local retaining variable.
- if (getLangOptions().ObjCAutoRefCount &&
+ if (getLangOpts().ObjCAutoRefCount &&
var->hasLocalStorage()) {
switch (var->getType().getObjCLifetime()) {
case Qualifiers::OCL_None:
@@ -6690,7 +6722,7 @@
}
// All the following checks are C++ only.
- if (!getLangOptions().CPlusPlus) return;
+ if (!getLangOpts().CPlusPlus) return;
QualType baseType = Context.getBaseElementType(var->getType());
if (baseType->isDependentType()) return;
@@ -6706,7 +6738,7 @@
if (type->isStructureOrClassType()) {
SourceLocation poi = var->getLocation();
- Expr *varRef = new (Context) DeclRefExpr(var, type, VK_LValue, poi);
+ Expr *varRef =new (Context) DeclRefExpr(var, false, type, VK_LValue, poi);
ExprResult result =
PerformCopyInitialization(
InitializedEntity::InitializeBlock(poi, type, false),
@@ -6747,7 +6779,7 @@
for (unsigned I = 0, N = Notes.size(); I != N; ++I)
Diag(Notes[I].first, Notes[I].second);
}
- } else if (var->isUsableInConstantExpressions()) {
+ } else if (var->isUsableInConstantExpressions(Context)) {
// Check whether the initializer of a const variable of integral or
// enumeration type is an ICE now, since we can't tell whether it was
// initialized by a constant expression if we check later.
@@ -6844,7 +6876,7 @@
if (DS.getStorageClassSpec() == DeclSpec::SCS_register) {
StorageClass = SC_Register;
StorageClassAsWritten = SC_Register;
- } else if (getLangOptions().CPlusPlus &&
+ } else if (getLangOpts().CPlusPlus &&
DS.getStorageClassSpec() == DeclSpec::SCS_auto) {
StorageClass = SC_Auto;
StorageClassAsWritten = SC_Auto;
@@ -6865,7 +6897,7 @@
TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
QualType parmDeclType = TInfo->getType();
- if (getLangOptions().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
// Check that there are no default arguments inside the type of this
// parameter.
CheckExtraCXXDefaultArguments(D);
@@ -6917,7 +6949,7 @@
// the enclosing context. This prevents them from accidentally
// looking like class members in C++.
ParmVarDecl *New = CheckParameter(Context.getTranslationUnitDecl(),
- D.getSourceRange().getBegin(),
+ D.getLocStart(),
D.getIdentifierLoc(), II,
parmDeclType, TInfo,
StorageClass, StorageClassAsWritten);
@@ -7015,7 +7047,7 @@
VarDecl::StorageClass StorageClass,
VarDecl::StorageClass StorageClassAsWritten) {
// In ARC, infer a lifetime qualifier for appropriate parameter types.
- if (getLangOptions().ObjCAutoRefCount &&
+ if (getLangOpts().ObjCAutoRefCount &&
T.getObjCLifetime() == Qualifiers::OCL_None &&
T->isObjCLifetimeType()) {
@@ -7168,11 +7200,11 @@
// was an extern inline function.
const FunctionDecl *Definition;
if (FD->isDefined(Definition) &&
- !canRedefineFunction(Definition, getLangOptions())) {
- if (getLangOptions().GNUMode && Definition->isInlineSpecified() &&
+ !canRedefineFunction(Definition, getLangOpts())) {
+ if (getLangOpts().GNUMode && Definition->isInlineSpecified() &&
Definition->getStorageClass() == SC_Extern)
Diag(FD->getLocation(), diag::err_redefinition_extern_inline)
- << FD->getDeclName() << getLangOptions().CPlusPlus;
+ << FD->getDeclName() << getLangOpts().CPlusPlus;
else
Diag(FD->getLocation(), diag::err_redefinition) << FD->getDeclName();
Diag(Definition->getLocation(), diag::note_previous_definition);
@@ -7370,7 +7402,7 @@
// MSVC permits the use of pure specifier (=0) on function definition,
// defined at class scope, warn about this non standard construct.
- if (getLangOptions().MicrosoftExt && FD->isPure())
+ if (getLangOpts().MicrosoftExt && FD->isPure())
Diag(FD->getLocation(), diag::warn_pure_function_definition);
if (!FD->isInvalidDecl()) {
@@ -7509,7 +7541,7 @@
unsigned diag_id;
if (II.getName().startswith("__builtin_"))
diag_id = diag::warn_builtin_unknown;
- else if (getLangOptions().C99)
+ else if (getLangOpts().C99)
diag_id = diag::ext_implicit_function_decl;
else
diag_id = diag::warn_implicit_function_decl;
@@ -7522,8 +7554,8 @@
DeclFilterCCC<FunctionDecl> Validator;
if (S && (Corrected = CorrectTypo(DeclarationNameInfo(&II, Loc),
LookupOrdinaryName, S, 0, Validator))) {
- std::string CorrectedStr = Corrected.getAsString(getLangOptions());
- std::string CorrectedQuotedStr = Corrected.getQuoted(getLangOptions());
+ std::string CorrectedStr = Corrected.getAsString(getLangOpts());
+ std::string CorrectedQuotedStr = Corrected.getQuoted(getLangOpts());
FunctionDecl *Func = Corrected.getCorrectionDeclAs<FunctionDecl>();
Diag(Loc, diag::note_function_suggestion) << CorrectedQuotedStr
@@ -7612,7 +7644,7 @@
// Mark const if we don't care about errno and that is the only
// thing preventing the function from being const. This allows
// IRgen to use LLVM intrinsics for such functions.
- if (!getLangOptions().MathErrno &&
+ if (!getLangOpts().MathErrno &&
Context.BuiltinInfo.isConstWithoutErrno(BuiltinID)) {
if (!FD->getAttr<ConstAttr>())
FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context));
@@ -7630,7 +7662,7 @@
IdentifierInfo *Name = FD->getIdentifier();
if (!Name)
return;
- if ((!getLangOptions().CPlusPlus &&
+ if ((!getLangOpts().CPlusPlus &&
FD->getDeclContext()->isTranslationUnit()) ||
(isa<LinkageSpecDecl>(FD->getDeclContext()) &&
cast<LinkageSpecDecl>(FD->getDeclContext())->getLanguage() ==
@@ -7662,7 +7694,7 @@
// Scope manipulation handled by caller.
TypedefDecl *NewTD = TypedefDecl::Create(Context, CurContext,
- D.getSourceRange().getBegin(),
+ D.getLocStart(),
D.getIdentifierLoc(),
D.getIdentifier(),
TInfo);
@@ -7721,6 +7753,50 @@
}
+/// \brief Check that this is a valid underlying type for an enum declaration.
+bool Sema::CheckEnumUnderlyingType(TypeSourceInfo *TI) {
+ SourceLocation UnderlyingLoc = TI->getTypeLoc().getBeginLoc();
+ QualType T = TI->getType();
+
+ if (T->isDependentType() || T->isIntegralType(Context))
+ return false;
+
+ Diag(UnderlyingLoc, diag::err_enum_invalid_underlying) << T;
+ return true;
+}
+
+/// Check whether this is a valid redeclaration of a previous enumeration.
+/// \return true if the redeclaration was invalid.
+bool Sema::CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped,
+ QualType EnumUnderlyingTy,
+ const EnumDecl *Prev) {
+ bool IsFixed = !EnumUnderlyingTy.isNull();
+
+ if (IsScoped != Prev->isScoped()) {
+ Diag(EnumLoc, diag::err_enum_redeclare_scoped_mismatch)
+ << Prev->isScoped();
+ Diag(Prev->getLocation(), diag::note_previous_use);
+ return true;
+ }
+
+ if (IsFixed && Prev->isFixed()) {
+ if (!Context.hasSameUnqualifiedType(EnumUnderlyingTy,
+ Prev->getIntegerType())) {
+ Diag(EnumLoc, diag::err_enum_redeclare_type_mismatch)
+ << EnumUnderlyingTy << Prev->getIntegerType();
+ Diag(Prev->getLocation(), diag::note_previous_use);
+ return true;
+ }
+ } else if (IsFixed != Prev->isFixed()) {
+ Diag(EnumLoc, diag::err_enum_redeclare_fixed_mismatch)
+ << Prev->isFixed();
+ Diag(Prev->getLocation(), diag::note_previous_use);
+ return true;
+ }
+
+ return false;
+}
+
/// \brief Determine whether a tag with a given kind is acceptable
/// as a redeclaration of the given tag declaration.
///
@@ -7893,23 +7969,18 @@
// C++0x 7.2p2: The type-specifier-seq of an enum-base shall name an
// integral type; any cv-qualification is ignored.
TypeSourceInfo *TI = 0;
- QualType T = GetTypeFromParser(UnderlyingType.get(), &TI);
+ GetTypeFromParser(UnderlyingType.get(), &TI);
EnumUnderlying = TI;
- SourceLocation UnderlyingLoc = TI->getTypeLoc().getBeginLoc();
-
- if (!T->isDependentType() && !T->isIntegralType(Context)) {
- Diag(UnderlyingLoc, diag::err_enum_invalid_underlying)
- << T;
+ if (CheckEnumUnderlyingType(TI))
// Recover by falling back to int.
EnumUnderlying = Context.IntTy.getTypePtr();
- }
- if (DiagnoseUnexpandedParameterPack(UnderlyingLoc, TI,
+ if (DiagnoseUnexpandedParameterPack(TI->getTypeLoc().getBeginLoc(), TI,
UPPC_FixedUnderlyingType))
EnumUnderlying = Context.IntTy.getTypePtr();
- } else if (getLangOptions().MicrosoftMode)
+ } else if (getLangOpts().MicrosoftMode)
// Microsoft enums are always of int type.
EnumUnderlying = Context.IntTy.getTypePtr();
}
@@ -7948,6 +8019,9 @@
<< SS.getRange();
return 0;
}
+
+ if (isa<CXXRecordDecl>(CurContext))
+ diagnoseQualifiedDeclInClass(SS, DC, Name, NameLoc);
}
if (RequireCompleteDeclContext(SS, DC))
@@ -8003,7 +8077,7 @@
if (Previous.isAmbiguous())
return 0;
- if (!getLangOptions().CPlusPlus && TUK != TUK_Reference) {
+ if (!getLangOpts().CPlusPlus && TUK != TUK_Reference) {
// FIXME: This makes sure that we ignore the contexts associated
// with C structs, unions, and enums when looking for a matching
// tag declaration or definition. See the similar lookup tweak
@@ -8014,6 +8088,7 @@
} else if (S->isFunctionPrototypeScope()) {
// If this is an enum declaration in function prototype scope, set its
// initial context to the translation unit.
+ // FIXME: [citation needed]
SearchDC = Context.getTranslationUnitDecl();
}
@@ -8025,7 +8100,7 @@
Previous.clear();
}
- if (getLangOptions().CPlusPlus && Name && DC && StdNamespace &&
+ if (getLangOpts().CPlusPlus && Name && DC && StdNamespace &&
DC->Equals(getStdNamespace()) && Name->isStr("bad_alloc")) {
// This is a declaration of or a reference to "std::bad_alloc".
isStdBadAlloc = true;
@@ -8076,13 +8151,12 @@
// Find the context where we'll be declaring the tag.
// FIXME: We would like to maintain the current DeclContext as the
// lexical context,
- while (SearchDC->isRecord() || SearchDC->isTransparentContext() ||
- SearchDC->isObjCContainer())
+ while (!SearchDC->isFileContext() && !SearchDC->isFunctionOrMethod())
SearchDC = SearchDC->getParent();
// Find the scope where we'll be declaring the tag.
while (S->isClassScope() ||
- (getLangOptions().CPlusPlus &&
+ (getLangOpts().CPlusPlus &&
S->isFunctionPrototypeScope()) ||
((S->getFlags() & Scope::DeclScope) == 0) ||
(S->getEntity() &&
@@ -8099,7 +8173,7 @@
// In C++, we need to do a redeclaration lookup to properly
// diagnose some problems.
- if (getLangOptions().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
Previous.setRedeclarationKind(ForRedeclaration);
LookupQualifiedName(Previous, SearchDC);
}
@@ -8117,7 +8191,7 @@
// technically forbidden by the current standard but which is
// okay according to the likely resolution of an open issue;
// see http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#407
- if (getLangOptions().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(PrevDecl)) {
if (const TagType *TT = TD->getUnderlyingType()->getAs<TagType>()) {
TagDecl *Tag = TT->getDecl();
@@ -8179,37 +8253,17 @@
return PrevTagDecl;
}
+ QualType EnumUnderlyingTy;
+ if (TypeSourceInfo *TI = EnumUnderlying.dyn_cast<TypeSourceInfo*>())
+ EnumUnderlyingTy = TI->getType();
+ else if (const Type *T = EnumUnderlying.dyn_cast<const Type*>())
+ EnumUnderlyingTy = QualType(T, 0);
+
// All conflicts with previous declarations are recovered by
// returning the previous declaration.
- if (ScopedEnum != PrevEnum->isScoped()) {
- Diag(KWLoc, diag::err_enum_redeclare_scoped_mismatch)
- << PrevEnum->isScoped();
- Diag(PrevTagDecl->getLocation(), diag::note_previous_use);
+ if (CheckEnumRedeclaration(NameLoc.isValid() ? NameLoc : KWLoc,
+ ScopedEnum, EnumUnderlyingTy, PrevEnum))
return PrevTagDecl;
- }
- else if (EnumUnderlying && PrevEnum->isFixed()) {
- QualType T;
- if (TypeSourceInfo *TI = EnumUnderlying.dyn_cast<TypeSourceInfo*>())
- T = TI->getType();
- else
- T = QualType(EnumUnderlying.get<const Type*>(), 0);
-
- if (!Context.hasSameUnqualifiedType(T,
- PrevEnum->getIntegerType())) {
- Diag(NameLoc.isValid() ? NameLoc : KWLoc,
- diag::err_enum_redeclare_type_mismatch)
- << T
- << PrevEnum->getIntegerType();
- Diag(PrevTagDecl->getLocation(), diag::note_previous_use);
- return PrevTagDecl;
- }
- }
- else if (!EnumUnderlying.isNull() != PrevEnum->isFixed()) {
- Diag(KWLoc, diag::err_enum_redeclare_fixed_mismatch)
- << PrevEnum->isFixed();
- Diag(PrevTagDecl->getLocation(), diag::note_previous_use);
- return PrevTagDecl;
- }
}
if (!Invalid) {
@@ -8220,7 +8274,7 @@
// For our current ASTs this shouldn't be a problem, but will
// need to be changed with DeclGroups.
if ((TUK == TUK_Reference && (!PrevTagDecl->getFriendObjectKind() ||
- getLangOptions().MicrosoftExt)) || TUK == TUK_Friend)
+ getLangOpts().MicrosoftExt)) || TUK == TUK_Friend)
return PrevTagDecl;
// Diagnose attempts to redefine a tag.
@@ -8235,7 +8289,7 @@
== TSK_ExplicitSpecialization) {
// A redeclaration in function prototype scope in C isn't
// visible elsewhere, so merely issue a warning.
- if (!getLangOptions().CPlusPlus && S->containedInPrototypeScope())
+ if (!getLangOpts().CPlusPlus && S->containedInPrototypeScope())
Diag(NameLoc, diag::warn_redefinition_in_param_list) << Name;
else
Diag(NameLoc, diag::err_redefinition) << Name;
@@ -8365,7 +8419,7 @@
// If this is an undefined enum, warn.
if (TUK != TUK_Definition && !Invalid) {
TagDecl *Def;
- if (getLangOptions().CPlusPlus0x && cast<EnumDecl>(New)->isFixed()) {
+ if (getLangOpts().CPlusPlus0x && cast<EnumDecl>(New)->isFixed()) {
// C++0x: 7.2p2: opaque-enum-declaration.
// Conflicts are diagnosed above. Do nothing.
}
@@ -8375,9 +8429,9 @@
Diag(Def->getLocation(), diag::note_previous_definition);
} else {
unsigned DiagID = diag::ext_forward_ref_enum;
- if (getLangOptions().MicrosoftMode)
+ if (getLangOpts().MicrosoftMode)
DiagID = diag::ext_ms_forward_ref_enum;
- else if (getLangOptions().CPlusPlus)
+ else if (getLangOpts().CPlusPlus)
DiagID = diag::err_forward_ref_enum;
Diag(Loc, DiagID);
@@ -8403,7 +8457,7 @@
// FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.:
// struct X { int A; } D; D should chain to X.
- if (getLangOptions().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
// FIXME: Look for a way to use RecordDecl for simple structs.
New = CXXRecordDecl::Create(Context, Kind, SearchDC, KWLoc, Loc, Name,
cast_or_null<CXXRecordDecl>(PrevDecl));
@@ -8469,7 +8523,7 @@
// If we're declaring or defining a tag in function prototype scope
// in C, note that this type can only be used within the function.
- if (Name && S->isFunctionPrototypeScope() && !getLangOptions().CPlusPlus)
+ if (Name && S->isFunctionPrototypeScope() && !getLangOpts().CPlusPlus)
Diag(Loc, diag::warn_decl_in_param_list) << Context.getTagDeclType(New);
// Set the lexical context. If the tag has a C++ scope specifier, the
@@ -8482,7 +8536,7 @@
// the tag name visible.
if (TUK == TUK_Friend)
New->setObjectOfFriendDecl(/* PreviouslyDeclared = */ !Previous.empty() ||
- getLangOptions().MicrosoftExt);
+ getLangOpts().MicrosoftExt);
// Set the access specifier.
if (!Invalid && SearchDC->isRecord())
@@ -8499,7 +8553,7 @@
New->setAccess(PrevDecl->getAccess());
DeclContext *DC = New->getDeclContext()->getRedeclContext();
- DC->makeDeclVisibleInContext(New, /* Recoverable = */ false);
+ DC->makeDeclVisibleInContext(New);
if (Name) // can be null along some error paths
if (Scope *EnclosingScope = getScopeForDeclContext(S, DC))
PushOnScopeChains(New, EnclosingScope, /* AddToContext = */ false);
@@ -8507,7 +8561,7 @@
S = getNonFieldDeclScope(S);
PushOnScopeChains(New, S, !IsForwardReference);
if (IsForwardReference)
- SearchDC->makeDeclVisibleInContext(New, /* Recoverable = */ false);
+ SearchDC->makeDeclVisibleInContext(New);
} else {
CurContext->addDecl(New);
@@ -8522,7 +8576,7 @@
// If we were in function prototype scope (and not in C++ mode), add this
// tag to the list of decls to inject into the function definition scope.
- if (S->isFunctionPrototypeScope() && !getLangOptions().CPlusPlus &&
+ if (S->isFunctionPrototypeScope() && !getLangOpts().CPlusPlus &&
InFunctionDeclarator && Name)
DeclsInPrototypeScope.push_back(New);
@@ -8589,6 +8643,13 @@
TagDecl *Tag = cast<TagDecl>(TagD);
Tag->setRBraceLoc(RBraceLoc);
+ // Make sure we "complete" the definition even it is invalid.
+ if (Tag->isBeingDefined()) {
+ assert(Tag->isInvalidDecl() && "We should already have completed it");
+ if (RecordDecl *RD = dyn_cast<RecordDecl>(Tag))
+ RD->completeDefinition();
+ }
+
if (isa<CXXRecordDecl>(Tag))
FieldCollector->FinishClass();
@@ -8620,6 +8681,12 @@
TagDecl *Tag = cast<TagDecl>(TagD);
Tag->setInvalidDecl();
+ // Make sure we "complete" the definition even it is invalid.
+ if (Tag->isBeingDefined()) {
+ if (RecordDecl *RD = dyn_cast<RecordDecl>(Tag))
+ RD->completeDefinition();
+ }
+
// We're undoing ActOnTagStartDefinition here, not
// ActOnStartCXXMemberDeclarations, so we don't have to mess with
// the FieldCollector.
@@ -8680,7 +8747,7 @@
if (!FieldTy->isDependentType()) {
uint64_t TypeSize = Context.getTypeSize(FieldTy);
if (Value.getZExtValue() > TypeSize) {
- if (!getLangOptions().CPlusPlus) {
+ if (!getLangOpts().CPlusPlus) {
if (FieldName)
return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_size)
<< FieldName << (unsigned)Value.getZExtValue()
@@ -8725,7 +8792,7 @@
TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
QualType T = TInfo->getType();
- if (getLangOptions().CPlusPlus) {
+ if (getLangOpts().CPlusPlus) {
CheckExtraCXXDefaultArguments(D);
if (DiagnoseUnexpandedParameterPack(D.getIdentifierLoc(), TInfo,
@@ -8777,7 +8844,7 @@
bool Mutable
= (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_mutable);
- SourceLocation TSSL = D.getSourceRange().getBegin();
+ SourceLocation TSSL = D.getLocStart();
FieldDecl *NewFD
= CheckFieldDecl(II, T, TInfo, Record, Loc, Mutable, BitWidth, HasInit,
TSSL, AS, PrevDecl, &D);
@@ -8828,11 +8895,19 @@
}
QualType EltTy = Context.getBaseElementType(T);
- if (!EltTy->isDependentType() &&
- RequireCompleteType(Loc, EltTy, diag::err_field_incomplete)) {
- // Fields of incomplete type force their record to be invalid.
- Record->setInvalidDecl();
- InvalidDecl = true;
+ if (!EltTy->isDependentType()) {
+ if (RequireCompleteType(Loc, EltTy, diag::err_field_incomplete)) {
+ // Fields of incomplete type force their record to be invalid.
+ Record->setInvalidDecl();
+ InvalidDecl = true;
+ } else {
+ NamedDecl *Def;
+ EltTy->isIncompleteType(&Def);
+ if (Def && Def->isInvalidDecl()) {
+ Record->setInvalidDecl();
+ InvalidDecl = true;
+ }
+ }
}
// C99 6.7.2.1p8: A member of a structure or union may have any type other
@@ -8904,7 +8979,7 @@
NewFD->setInvalidDecl();
}
- if (!InvalidDecl && getLangOptions().CPlusPlus) {
+ if (!InvalidDecl && getLangOpts().CPlusPlus) {
if (Record->isUnion()) {
if (const RecordType *RT = EltTy->getAs<RecordType>()) {
CXXRecordDecl* RDecl = cast<CXXRecordDecl>(RT->getDecl());
@@ -8937,7 +9012,7 @@
// In auto-retain/release, infer strong retension for fields of
// retainable type.
- if (getLangOptions().ObjCAutoRefCount && inferObjCARCLifetime(NewFD))
+ if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(NewFD))
NewFD->setInvalidDecl();
if (T.isObjCGCWeak())
@@ -8949,7 +9024,7 @@
bool Sema::CheckNontrivialField(FieldDecl *FD) {
assert(FD);
- assert(getLangOptions().CPlusPlus && "valid check only for C++");
+ assert(getLangOpts().CPlusPlus && "valid check only for C++");
if (FD->isInvalidDecl())
return true;
@@ -8973,8 +9048,8 @@
member = CXXDestructor;
if (member != CXXInvalid) {
- if (!getLangOptions().CPlusPlus0x &&
- getLangOptions().ObjCAutoRefCount && RDecl->hasObjectMember()) {
+ if (!getLangOpts().CPlusPlus0x &&
+ getLangOpts().ObjCAutoRefCount && RDecl->hasObjectMember()) {
// Objective-C++ ARC: it is an error to have a non-trivial field of
// a union. However, system headers in Objective-C programs
// occasionally have Objective-C lifetime objects within unions,
@@ -8989,12 +9064,12 @@
}
}
- Diag(FD->getLocation(), getLangOptions().CPlusPlus0x ?
+ Diag(FD->getLocation(), getLangOpts().CPlusPlus0x ?
diag::warn_cxx98_compat_nontrivial_union_or_anon_struct_member :
diag::err_illegal_union_or_anon_struct_member)
<< (int)FD->getParent()->isUnion() << FD->getDeclName() << member;
DiagnoseNontrivial(RT, member);
- return !getLangOptions().CPlusPlus0x;
+ return !getLangOpts().CPlusPlus0x;
}
}
}
@@ -9067,7 +9142,7 @@
if (RD->hasUserDeclaredCopyAssignment()) {
// FIXME: this should use the location of the copy
// assignment, not the type.
- SourceLocation TyLoc = RD->getSourceRange().getBegin();
+ SourceLocation TyLoc = RD->getLocStart();
Diag(TyLoc, diag::note_nontrivial_user_defined) << QT << member;
return;
}
@@ -9099,7 +9174,7 @@
// so we just iterate through the direct bases.
for (base_iter bi = RD->bases_begin(), be = RD->bases_end(); bi != be; ++bi)
if (bi->isVirtual()) {
- SourceLocation BaseLoc = bi->getSourceRange().getBegin();
+ SourceLocation BaseLoc = bi->getLocStart();
Diag(BaseLoc, diag::note_nontrivial_has_virtual) << QT << 1;
return;
}
@@ -9109,7 +9184,7 @@
for (meth_iter mi = RD->method_begin(), me = RD->method_end(); mi != me;
++mi) {
if (mi->isVirtual()) {
- SourceLocation MLoc = mi->getSourceRange().getBegin();
+ SourceLocation MLoc = mi->getLocStart();
Diag(MLoc, diag::note_nontrivial_has_virtual) << QT << 0;
return;
}
@@ -9136,7 +9211,7 @@
assert(BaseRT && "Don't know how to handle dependent bases");
CXXRecordDecl *BaseRecTy = cast<CXXRecordDecl>(BaseRT->getDecl());
if (!(BaseRecTy->*hasTrivial)()) {
- SourceLocation BaseLoc = bi->getSourceRange().getBegin();
+ SourceLocation BaseLoc = bi->getLocStart();
Diag(BaseLoc, diag::note_nontrivial_has_nontrivial) << QT << 1 << member;
DiagnoseNontrivial(BaseRT, member);
return;
@@ -9283,7 +9358,7 @@
NewID->setInvalidDecl();
// In ARC, infer 'retaining' for ivars of retainable type.
- if (getLangOptions().ObjCAutoRefCount && inferObjCARCLifetime(NewID))
+ if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(NewID))
NewID->setInvalidDecl();
if (D.getDeclSpec().isModulePrivateSpecified())
@@ -9405,27 +9480,34 @@
continue;
} else if (FDTy->isIncompleteArrayType() && Record &&
((i + 1 == Fields.end() && !Record->isUnion()) ||
- ((getLangOptions().MicrosoftExt ||
- getLangOptions().CPlusPlus) &&
+ ((getLangOpts().MicrosoftExt ||
+ getLangOpts().CPlusPlus) &&
(i + 1 == Fields.end() || Record->isUnion())))) {
// Flexible array member.
// Microsoft and g++ is more permissive regarding flexible array.
// It will accept flexible array in union and also
// as the sole element of a struct/class.
- if (getLangOptions().MicrosoftExt) {
+ if (getLangOpts().MicrosoftExt) {
if (Record->isUnion())
Diag(FD->getLocation(), diag::ext_flexible_array_union_ms)
<< FD->getDeclName();
else if (Fields.size() == 1)
Diag(FD->getLocation(), diag::ext_flexible_array_empty_aggregate_ms)
<< FD->getDeclName() << Record->getTagKind();
- } else if (getLangOptions().CPlusPlus) {
+ } else if (getLangOpts().CPlusPlus) {
if (Record->isUnion())
Diag(FD->getLocation(), diag::ext_flexible_array_union_gnu)
<< FD->getDeclName();
else if (Fields.size() == 1)
Diag(FD->getLocation(), diag::ext_flexible_array_empty_aggregate_gnu)
<< FD->getDeclName() << Record->getTagKind();
+ } else if (!getLangOpts().C99) {
+ if (Record->isUnion())
+ Diag(FD->getLocation(), diag::ext_flexible_array_union_gnu)
+ << FD->getDeclName();
+ else
+ Diag(FD->getLocation(), diag::ext_c99_flexible_array_member)
+ << FD->getDeclName() << Record->getTagKind();
} else if (NumNamedMembers < 1) {
Diag(FD->getLocation(), diag::err_flexible_array_empty_struct)
<< FD->getDeclName();
@@ -9482,8 +9564,8 @@
QualType T = Context.getObjCObjectPointerType(FD->getType());
FD->setType(T);
}
- else if (!getLangOptions().CPlusPlus) {
- if (getLangOptions().ObjCAutoRefCount && Record && !ARCErrReported) {
+ else if (!getLangOpts().CPlusPlus) {
+ if (getLangOpts().ObjCAutoRefCount && Record && !ARCErrReported) {
// It's an error in ARC if a field has lifetime.
// We don't want to report this in a system header, though,
// so we just make the field unavailable.
@@ -9505,8 +9587,8 @@
ARCErrReported = true;
}
}
- else if (getLangOptions().ObjC1 &&
- getLangOptions().getGC() != LangOptions::NonGC &&
+ else if (getLangOpts().ObjC1 &&
+ getLangOpts().getGC() != LangOptions::NonGC &&
Record && !Record->hasObjectMember()) {
if (FD->getType()->isObjCObjectPointerType() ||
FD->getType().isObjCGCStrong())
@@ -9550,7 +9632,7 @@
// non-POD because of the presence of an Objective-C pointer member.
// If so, objects of this type cannot be shared between code compiled
// with instant objects and code compiled with manual retain/release.
- if (getLangOptions().ObjCAutoRefCount &&
+ if (getLangOpts().ObjCAutoRefCount &&
CXXRecord->hasObjectMember() &&
CXXRecord->getLinkage() == ExternalLinkage) {
if (CXXRecord->isPOD()) {
@@ -9576,7 +9658,7 @@
}
// Adjust user-defined destructor exception spec.
- if (getLangOptions().CPlusPlus0x &&
+ if (getLangOpts().CPlusPlus0x &&
CXXRecord->hasUserDeclaredDestructor())
AdjustDestructorExceptionSpec(CXXRecord,CXXRecord->getDestructor());
@@ -9776,8 +9858,8 @@
EltTy = Context.DependentTy;
else {
SourceLocation ExpLoc;
- if (getLangOptions().CPlusPlus0x && Enum->isFixed() &&
- !getLangOptions().MicrosoftMode) {
+ if (getLangOpts().CPlusPlus0x && Enum->isFixed() &&
+ !getLangOpts().MicrosoftMode) {
// C++11 [dcl.enum]p5: If the underlying type is fixed, [...] the
// constant-expression in the enumerator-definition shall be a converted
// constant expression of the underlying type.
@@ -9802,14 +9884,14 @@
// we perform a non-narrowing conversion as part of converted constant
// expression checking.
if (!isRepresentableIntegerValue(Context, EnumVal, EltTy)) {
- if (getLangOptions().MicrosoftMode) {
+ if (getLangOpts().MicrosoftMode) {
Diag(IdLoc, diag::ext_enumerator_too_large) << EltTy;
Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).take();
} else
Diag(IdLoc, diag::err_enumerator_too_large) << EltTy;
} else
Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).take();
- } else if (getLangOptions().CPlusPlus) {
+ } else if (getLangOpts().CPlusPlus) {
// C++11 [dcl.enum]p5:
// If the underlying type is not fixed, the type of each enumerator
// is the type of its initializing value:
@@ -9905,9 +9987,9 @@
// an int (C99 6.7.2.2p2). However, we support GCC's extension that
// permits enumerator values that are representable in some larger
// integral type.
- if (!getLangOptions().CPlusPlus && !T.isNull())
+ if (!getLangOpts().CPlusPlus && !T.isNull())
Diag(IdLoc, diag::warn_enum_value_overflow);
- } else if (!getLangOptions().CPlusPlus &&
+ } else if (!getLangOpts().CPlusPlus &&
!isRepresentableIntegerValue(Context, EnumVal, EltTy)) {
// Enforce C99 6.7.2.2p2 even when we compute the next value.
Diag(IdLoc, diag::ext_enum_value_not_int)
@@ -9954,7 +10036,7 @@
if (PrevDecl) {
// When in C++, we may get a TagDecl with the same name; in this case the
// enum constant will 'hide' the tag.
- assert((getLangOptions().CPlusPlus || !isa<TagDecl>(PrevDecl)) &&
+ assert((getLangOpts().CPlusPlus || !isa<TagDecl>(PrevDecl)) &&
"Received TagDecl when not in C++!");
if (!isa<TagDecl>(PrevDecl) && isDeclInScope(PrevDecl, CurContext, S)) {
if (isa<EnumConstantDecl>(PrevDecl))
@@ -10126,13 +10208,13 @@
BestType = Context.UnsignedIntTy;
BestWidth = IntWidth;
BestPromotionType
- = (NumPositiveBits == BestWidth || !getLangOptions().CPlusPlus)
+ = (NumPositiveBits == BestWidth || !getLangOpts().CPlusPlus)
? Context.UnsignedIntTy : Context.IntTy;
} else if (NumPositiveBits <=
(BestWidth = Context.getTargetInfo().getLongWidth())) {
BestType = Context.UnsignedLongTy;
BestPromotionType
- = (NumPositiveBits == BestWidth || !getLangOptions().CPlusPlus)
+ = (NumPositiveBits == BestWidth || !getLangOpts().CPlusPlus)
? Context.UnsignedLongTy : Context.LongTy;
} else {
BestWidth = Context.getTargetInfo().getLongLongWidth();
@@ -10140,7 +10222,7 @@
"How could an initializer get larger than ULL?");
BestType = Context.UnsignedLongLongTy;
BestPromotionType
- = (NumPositiveBits == BestWidth || !getLangOptions().CPlusPlus)
+ = (NumPositiveBits == BestWidth || !getLangOpts().CPlusPlus)
? Context.UnsignedLongLongTy : Context.LongLongTy;
}
}
@@ -10165,7 +10247,7 @@
QualType NewTy;
unsigned NewWidth;
bool NewSign;
- if (!getLangOptions().CPlusPlus &&
+ if (!getLangOpts().CPlusPlus &&
!Enum->isFixed() &&
isRepresentableIntegerValue(Context, InitVal, Context.IntTy)) {
NewTy = Context.IntTy;
@@ -10173,7 +10255,7 @@
NewSign = true;
} else if (ECD->getType() == BestType) {
// Already the right type!
- if (getLangOptions().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
// C++ [dcl.enum]p4: Following the closing brace of an
// enum-specifier, each enumerator has the type of its
// enumeration.
@@ -10198,7 +10280,7 @@
ECD->getInitExpr(),
/*base paths*/ 0,
VK_RValue));
- if (getLangOptions().CPlusPlus)
+ if (getLangOpts().CPlusPlus)
// C++ [dcl.enum]p4: Following the closing brace of an
// enum-specifier, each enumerator has the type of its
// enumeration.
More information about the llvm-branch-commits
mailing list