summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-03-10 17:45:58 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-03-10 17:45:58 +0000
commit27c39af73c0d7d0b97e57b3a905040d4cefc9708 (patch)
tree56c1dd85a159948815817b5a90bedb39cf9ad105
parentd2e6cf1d1c6468396ec057119c32aa58b1ee5ac9 (diff)
downloadFreeBSD-src-27c39af73c0d7d0b97e57b3a905040d4cefc9708.zip
FreeBSD-src-27c39af73c0d7d0b97e57b3a905040d4cefc9708.tar.gz
Update clang to r98164.
-rw-r--r--bindings/python/clang/cindex.py182
-rw-r--r--include/clang-c/Index.h6
-rw-r--r--include/clang/AST/ASTContext.h23
-rw-r--r--include/clang/AST/Decl.h1
-rw-r--r--include/clang/AST/DeclObjC.h16
-rw-r--r--include/clang/AST/DeclTemplate.h22
-rw-r--r--include/clang/AST/ExprObjC.h30
-rw-r--r--include/clang/AST/PrettyPrinter.h7
-rw-r--r--include/clang/AST/RecordLayout.h39
-rw-r--r--include/clang/AST/Type.h41
-rw-r--r--include/clang/AST/TypeLoc.h8
-rw-r--r--include/clang/AST/TypeNodes.def1
-rw-r--r--include/clang/Basic/BuiltinsX86.def3
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td3
-rw-r--r--include/clang/Basic/DiagnosticGroups.td8
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td22
-rw-r--r--include/clang/Checker/PathSensitive/SVals.h3
-rw-r--r--include/clang/Frontend/CompilerInstance.h4
-rw-r--r--include/clang/Frontend/DeclXML.def19
-rw-r--r--include/clang/Frontend/PCHBitCodes.h4
-rw-r--r--include/clang/Lex/Preprocessor.h20
-rw-r--r--include/clang/Parse/DeclSpec.h3
-rw-r--r--lib/AST/ASTContext.cpp113
-rw-r--r--lib/AST/ASTDiagnostic.cpp6
-rw-r--r--lib/AST/ASTImporter.cpp14
-rw-r--r--lib/AST/CMakeLists.txt3
-rw-r--r--lib/AST/DeclBase.cpp21
-rw-r--r--lib/AST/DeclCXX.cpp15
-rw-r--r--lib/AST/DeclObjC.cpp7
-rw-r--r--lib/AST/DeclTemplate.cpp8
-rw-r--r--lib/AST/Expr.cpp35
-rw-r--r--lib/AST/NestedNameSpecifier.cpp1
-rw-r--r--lib/AST/RecordLayout.cpp67
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp35
-rw-r--r--lib/AST/Type.cpp1
-rw-r--r--lib/AST/TypePrinter.cpp164
-rw-r--r--lib/Analysis/AnalysisContext.cpp26
-rw-r--r--lib/Basic/Targets.cpp131
-rw-r--r--lib/Checker/BasicStore.cpp3
-rw-r--r--lib/Checker/CFRefCount.cpp4
-rw-r--r--lib/Checker/GRExprEngine.cpp1
-rw-r--r--lib/Checker/MallocChecker.cpp24
-rw-r--r--lib/Checker/RegionStore.cpp793
-rw-r--r--lib/Checker/SVals.cpp19
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp253
-rw-r--r--lib/CodeGen/CGDebugInfo.h73
-rw-r--r--lib/CodeGen/CGExprAgg.cpp24
-rw-r--r--lib/CodeGen/CGObjC.cpp2
-rw-r--r--lib/CodeGen/CGVtable.cpp225
-rw-r--r--lib/CodeGen/CGVtable.h18
-rw-r--r--lib/CodeGen/CodeGenModule.cpp10
-rw-r--r--lib/CodeGen/CodeGenModule.h4
-rw-r--r--lib/CodeGen/Mangle.cpp6
-rw-r--r--lib/Driver/HostInfo.cpp2
-rw-r--r--lib/Driver/Tools.cpp4
-rw-r--r--lib/Frontend/CacheTokens.cpp4
-rw-r--r--lib/Frontend/CompilerInstance.cpp4
-rw-r--r--lib/Frontend/DeclXML.cpp26
-rw-r--r--lib/Frontend/DependencyFile.cpp3
-rw-r--r--lib/Frontend/FrontendAction.cpp2
-rw-r--r--lib/Frontend/InitHeaderSearch.cpp2
-rw-r--r--lib/Frontend/PCHReader.cpp37
-rw-r--r--lib/Frontend/PCHReaderDecl.cpp3
-rw-r--r--lib/Frontend/PCHReaderStmt.cpp5
-rw-r--r--lib/Frontend/PCHWriter.cpp9
-rw-r--r--lib/Frontend/PCHWriterDecl.cpp1
-rw-r--r--lib/Frontend/PCHWriterStmt.cpp5
-rw-r--r--lib/Frontend/PrintPreprocessedOutput.cpp8
-rw-r--r--lib/Headers/smmintrin.h125
-rw-r--r--lib/Headers/stdarg.h3
-rw-r--r--lib/Headers/stddef.h7
-rw-r--r--lib/Index/Analyzer.cpp4
-rw-r--r--lib/Sema/CodeCompleteConsumer.cpp1
-rw-r--r--lib/Sema/JumpDiagnostics.cpp2
-rw-r--r--lib/Sema/SemaCXXCast.cpp38
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp23
-rw-r--r--lib/Sema/SemaDecl.cpp65
-rw-r--r--lib/Sema/SemaDeclCXX.cpp81
-rw-r--r--lib/Sema/SemaDeclObjC.cpp8
-rw-r--r--lib/Sema/SemaExpr.cpp3
-rw-r--r--lib/Sema/SemaExprCXX.cpp20
-rw-r--r--lib/Sema/SemaExprObjC.cpp12
-rw-r--r--lib/Sema/SemaInit.cpp30
-rw-r--r--lib/Sema/SemaTemplate.cpp26
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp9
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp38
-rw-r--r--lib/Sema/TreeTransform.h14
-rw-r--r--test/Analysis/dead-stores.c26
-rw-r--r--test/Analysis/malloc.c6
-rw-r--r--test/CMakeLists.txt1
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp4
-rw-r--r--test/CXX/class.access/class.friend/p1.cpp18
-rw-r--r--test/CXX/class/class.friend/p1.cpp2
-rw-r--r--test/CXX/class/class.local/p2.cpp2
-rw-r--r--test/CXX/class/class.union/p1.cpp42
-rw-r--r--test/CXX/conv/conv.mem/p4.cpp16
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp4
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp10
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp28
-rw-r--r--test/CXX/dcl.decl/dcl.init/p6.cpp5
-rw-r--r--test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp4
-rw-r--r--test/CodeCompletion/call.cpp4
-rw-r--r--test/CodeCompletion/enum-switch-case-qualified.cpp14
-rw-r--r--test/CodeCompletion/enum-switch-case.cpp10
-rw-r--r--test/CodeGen/2010-03-09-DbgInfo.c2
-rw-r--r--test/CodeGen/init.c11
-rw-r--r--test/CodeGenCXX/2010-03-09-AnonAggregate.cpp12
-rw-r--r--test/CodeGenCXX/PR6474.cpp31
-rw-r--r--test/CodeGenCXX/default-destructor-nested.cpp13
-rw-r--r--test/CodeGenCXX/internal-linkage.cpp6
-rw-r--r--test/CodeGenCXX/mangle-system-header.cpp4
-rw-r--r--test/CodeGenCXX/nullptr.cpp12
-rw-r--r--test/CodeGenCXX/virtual-base-destructor-call.cpp10
-rw-r--r--test/CodeGenCXX/vtable-layout-abi-examples.cpp123
-rw-r--r--test/CodeGenCXX/vtable-layout.cpp55
-rw-r--r--test/CodeGenObjC/id-isa-codegen.m9
-rw-r--r--test/Driver/clang-g-opts.c5
-rw-r--r--test/FixIt/typo.cpp6
-rw-r--r--test/Headers/typedef_guards.c28
-rw-r--r--test/Index/annotate-tokens.m49
-rw-r--r--test/Index/c-index-getCursor-test.m8
-rw-r--r--test/Index/code-completion.cpp10
-rw-r--r--test/Parser/altivec.c40
-rw-r--r--test/Parser/cxx-altivec.cpp36
-rw-r--r--test/Sema/warn-missing-braces.c3
-rw-r--r--test/SemaCXX/access-base-class.cpp6
-rw-r--r--test/SemaCXX/access-control-check.cpp2
-rw-r--r--test/SemaCXX/aggregate-initialization.cpp12
-rw-r--r--test/SemaCXX/ambig-user-defined-conversions.cpp2
-rw-r--r--test/SemaCXX/arrow-operator.cpp2
-rw-r--r--test/SemaCXX/attr-cxx0x.cpp2
-rw-r--r--test/SemaCXX/builtin-ptrtomember-overload-1.cpp2
-rw-r--r--test/SemaCXX/cast-conversion.cpp6
-rw-r--r--test/SemaCXX/class-base-member-init.cpp2
-rw-r--r--test/SemaCXX/conditional-expr.cpp22
-rw-r--r--test/SemaCXX/const-cast.cpp2
-rw-r--r--test/SemaCXX/constructor-initializer.cpp10
-rw-r--r--test/SemaCXX/conversion-delete-expr.cpp6
-rw-r--r--test/SemaCXX/conversion-function.cpp10
-rw-r--r--test/SemaCXX/convert-to-bool.cpp6
-rw-r--r--test/SemaCXX/copy-assignment.cpp2
-rw-r--r--test/SemaCXX/copy-initialization.cpp4
-rw-r--r--test/SemaCXX/cstyle-cast.cpp22
-rw-r--r--test/SemaCXX/dcl_init_aggr.cpp6
-rw-r--r--test/SemaCXX/decl-init-ref.cpp6
-rw-r--r--test/SemaCXX/decltype-overloaded-functions.cpp2
-rw-r--r--test/SemaCXX/default-assignment-operator.cpp6
-rw-r--r--test/SemaCXX/default-constructor-initializers.cpp5
-rw-r--r--test/SemaCXX/default2.cpp4
-rw-r--r--test/SemaCXX/deleted-function.cpp2
-rw-r--r--test/SemaCXX/derived-to-base-ambig.cpp4
-rw-r--r--test/SemaCXX/destructor.cpp2
-rw-r--r--test/SemaCXX/direct-initializer.cpp6
-rw-r--r--test/SemaCXX/dynamic-cast.cpp16
-rw-r--r--test/SemaCXX/elaborated-type-specifier.cpp2
-rw-r--r--test/SemaCXX/exception-spec.cpp6
-rw-r--r--test/SemaCXX/exceptions.cpp10
-rw-r--r--test/SemaCXX/functional-cast.cpp22
-rw-r--r--test/SemaCXX/illegal-member-initialization.cpp8
-rw-r--r--test/SemaCXX/implicit-virtual-member-functions.cpp6
-rw-r--r--test/SemaCXX/incomplete-call.cpp30
-rw-r--r--test/SemaCXX/inherit.cpp6
-rw-r--r--test/SemaCXX/member-name-lookup.cpp12
-rw-r--r--test/SemaCXX/member-pointer.cpp14
-rw-r--r--test/SemaCXX/missing-members.cpp12
-rw-r--r--test/SemaCXX/nested-name-spec.cpp14
-rw-r--r--test/SemaCXX/new-delete.cpp12
-rw-r--r--test/SemaCXX/offsetof.cpp2
-rw-r--r--test/SemaCXX/overload-call.cpp20
-rw-r--r--test/SemaCXX/overload-member-call.cpp8
-rw-r--r--test/SemaCXX/overloaded-operator.cpp8
-rw-r--r--test/SemaCXX/qual-id-test.cpp4
-rw-r--r--test/SemaCXX/qualified-id-lookup.cpp4
-rw-r--r--test/SemaCXX/qualified-names-diag.cpp2
-rw-r--r--test/SemaCXX/ref-init-ambiguous.cpp6
-rw-r--r--test/SemaCXX/references.cpp2
-rw-r--r--test/SemaCXX/reinterpret-cast.cpp12
-rw-r--r--test/SemaCXX/rval-references.cpp4
-rw-r--r--test/SemaCXX/statements.cpp5
-rw-r--r--test/SemaCXX/static-assert.cpp4
-rw-r--r--test/SemaCXX/static-cast-complete-type.cpp4
-rw-r--r--test/SemaCXX/static-cast.cpp48
-rw-r--r--test/SemaCXX/type-traits-incomplete.cpp4
-rw-r--r--test/SemaCXX/typedef-redecl.cpp4
-rw-r--r--test/SemaCXX/typeid.cpp6
-rw-r--r--test/SemaCXX/unknown-type-name.cpp4
-rw-r--r--test/SemaCXX/using-decl-templates.cpp2
-rw-r--r--test/SemaCXX/value-initialization.cpp2
-rw-r--r--test/SemaCXX/vararg-non-pod.cpp16
-rw-r--r--test/SemaCXX/vector-casts.cpp8
-rw-r--r--test/SemaCXX/virtual-member-functions-key-function.cpp4
-rw-r--r--test/SemaCXX/virtual-override.cpp22
-rw-r--r--test/SemaCXX/warn-reorder-ctor-initialization.cpp22
-rw-r--r--test/SemaObjC/blocks.m12
-rw-r--r--test/SemaObjC/exprs.m5
-rw-r--r--test/SemaObjCXX/cstyle-cast.mm2
-rw-r--r--test/SemaObjCXX/vararg-non-pod.mm2
-rw-r--r--test/SemaTemplate/class-template-id-2.cpp2
-rw-r--r--test/SemaTemplate/class-template-spec.cpp2
-rw-r--r--test/SemaTemplate/default-expr-arguments.cpp10
-rw-r--r--test/SemaTemplate/dependent-base-classes.cpp4
-rw-r--r--test/SemaTemplate/ext-vector-type.cpp2
-rw-r--r--test/SemaTemplate/injected-class-name.cpp6
-rw-r--r--test/SemaTemplate/instantiate-cast.cpp6
-rw-r--r--test/SemaTemplate/instantiate-complete.cpp10
-rw-r--r--test/SemaTemplate/instantiate-exception-spec.cpp2
-rw-r--r--test/SemaTemplate/instantiate-expr-1.cpp14
-rw-r--r--test/SemaTemplate/instantiate-expr-4.cpp2
-rw-r--r--test/SemaTemplate/instantiate-field.cpp4
-rw-r--r--test/SemaTemplate/instantiate-function-1.cpp2
-rw-r--r--test/SemaTemplate/instantiate-member-class.cpp4
-rw-r--r--test/SemaTemplate/instantiate-member-expr.cpp6
-rw-r--r--test/SemaTemplate/instantiate-method.cpp4
-rw-r--r--test/SemaTemplate/instantiate-static-var.cpp4
-rw-r--r--test/SemaTemplate/instantiate-typedef.cpp4
-rw-r--r--test/SemaTemplate/instantiation-backtrace.cpp10
-rw-r--r--test/SemaTemplate/metafun-apply.cpp6
-rw-r--r--test/SemaTemplate/temp_arg_nontype.cpp12
-rw-r--r--test/SemaTemplate/temp_arg_type.cpp2
-rw-r--r--test/SemaTemplate/typename-specifier-4.cpp17
-rw-r--r--test/SemaTemplate/typename-specifier.cpp20
-rw-r--r--test/SemaTemplate/virtual-member-functions.cpp4
-rw-r--r--test/lit.cfg12
-rw-r--r--tools/CIndex/CIndex.cpp28
-rw-r--r--tools/CIndex/CIndex.exports1
-rw-r--r--tools/Makefile7
-rw-r--r--tools/driver/driver.cpp4
-rwxr-xr-xtools/scan-build/ccc-analyzer13
229 files changed, 2977 insertions, 1700 deletions
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index c37c69b..f4409ae 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -187,12 +187,56 @@ class Diagnostic(object):
Error = 3
Fatal = 4
- def __init__(self, severity, location, spelling, ranges, fixits):
- self.severity = severity
- self.location = location
- self.spelling = spelling
- self.ranges = ranges
- self.fixits = fixits
+ def __init__(self, ptr):
+ self.ptr = ptr
+
+ def __del__(self):
+ _clang_disposeDiagnostic(self.ptr)
+
+ @property
+ def severity(self):
+ return _clang_getDiagnosticSeverity(self.ptr)
+
+ @property
+ def location(self):
+ return _clang_getDiagnosticLocation(self.ptr)
+
+ @property
+ def spelling(self):
+ return _clang_getDiagnosticSpelling(self.ptr)
+
+ @property
+ def ranges(self):
+ class RangeIterator:
+ def __init__(self, diag):
+ self.diag = diag
+
+ def __len__(self):
+ return int(_clang_getDiagnosticNumRanges(self.diag))
+
+ def __getitem__(self, key):
+ return _clang_getDiagnosticRange(self.diag, key)
+
+ return RangeIterator(self.ptr)
+
+ @property
+ def fixits(self):
+ class FixItIterator:
+ def __init__(self, diag):
+ self.diag = diag
+
+ def __len__(self):
+ return int(_clang_getDiagnosticNumFixIts(self.diag))
+
+ def __getitem__(self, key):
+ range = SourceRange()
+ value = _clang_getDiagnosticFixIt(self.diag, key, byref(range))
+ if len(value) == 0:
+ raise IndexError
+
+ return FixIt(range, value)
+
+ return FixItIterator(self.ptr)
def __repr__(self):
return "<Diagnostic severity %r, location %r, spelling %r>" % (
@@ -539,8 +583,16 @@ class _CXUnsavedFile(Structure):
## Diagnostic Conversion ##
-# Diagnostic objects are temporary, we must extract all the information from the
-# diagnostic object when it is passed to the callback.
+_clang_getNumDiagnostics = lib.clang_getNumDiagnostics
+_clang_getNumDiagnostics.argtypes = [c_object_p]
+_clang_getNumDiagnostics.restype = c_uint
+
+_clang_getDiagnostic = lib.clang_getDiagnostic
+_clang_getDiagnostic.argtypes = [c_object_p, c_uint]
+_clang_getDiagnostic.restype = c_object_p
+
+_clang_disposeDiagnostic = lib.clang_disposeDiagnostic
+_clang_disposeDiagnostic.argtypes = [c_object_p]
_clang_getDiagnosticSeverity = lib.clang_getDiagnosticSeverity
_clang_getDiagnosticSeverity.argtypes = [c_object_p]
@@ -567,67 +619,10 @@ _clang_getDiagnosticNumFixIts = lib.clang_getDiagnosticNumFixIts
_clang_getDiagnosticNumFixIts.argtypes = [c_object_p]
_clang_getDiagnosticNumFixIts.restype = c_uint
-_clang_getDiagnosticFixItKind = lib.clang_getDiagnosticFixItKind
-_clang_getDiagnosticFixItKind.argtypes = [c_object_p, c_uint]
-_clang_getDiagnosticFixItKind.restype = c_int
-
-_clang_getDiagnosticFixItInsertion = lib.clang_getDiagnosticFixItInsertion
-_clang_getDiagnosticFixItInsertion.argtypes = [c_object_p, c_uint,
- POINTER(SourceLocation)]
-_clang_getDiagnosticFixItInsertion.restype = _CXString
-_clang_getDiagnosticFixItInsertion.errcheck = _CXString.from_result
-
-_clang_getDiagnosticFixItRemoval = lib.clang_getDiagnosticFixItRemoval
-_clang_getDiagnosticFixItRemoval.argtypes = [c_object_p, c_uint,
- POINTER(SourceLocation)]
-_clang_getDiagnosticFixItRemoval.restype = _CXString
-_clang_getDiagnosticFixItRemoval.errcheck = _CXString.from_result
-
-_clang_getDiagnosticFixItReplacement = lib.clang_getDiagnosticFixItReplacement
-_clang_getDiagnosticFixItReplacement.argtypes = [c_object_p, c_uint,
- POINTER(SourceRange)]
-_clang_getDiagnosticFixItReplacement.restype = _CXString
-_clang_getDiagnosticFixItReplacement.errcheck = _CXString.from_result
-
-def _convert_fixit(diag_ptr, index):
- # We normalize all the fix-its to a single representation, this is more
- # convenient.
- #
- # FIXME: Push this back into API? It isn't exactly clear what the
- # SourceRange semantics are, we should make sure we can represent an empty
- # range.
- kind = _clang_getDiagnosticFixItKind(diag_ptr, index)
- range = None
- value = None
- if kind == 0: # insertion
- location = SourceLocation()
- value = _clang_getDiagnosticFixItInsertion(diag_ptr, index,
- byref(location))
- range = SourceRange.from_locations(location, location)
- elif kind == 1: # removal
- range = _clang_getDiagnosticFixItRemoval(diag_ptr, index)
- value = ''
- else: # replacement
- assert kind == 2
- range = SourceRange()
- value = _clang_getDiagnosticFixItReplacement(diag_ptr, index,
- byref(range))
- return FixIt(range, value)
-
-def _convert_diag(diag_ptr, diag_list):
- severity = _clang_getDiagnosticSeverity(diag_ptr)
- loc = _clang_getDiagnosticLocation(diag_ptr)
- spelling = _clang_getDiagnosticSpelling(diag_ptr)
-
- # Diagnostic ranges.
- num_ranges = _clang_getDiagnosticNumRanges(diag_ptr)
- ranges = [_clang_getDiagnosticRange(diag_ptr, i)
- for i in range(num_ranges)]
-
- fixits = [_convert_fixit(diag_ptr, i)
- for i in range(_clang_getDiagnosticNumFixIts(diag_ptr))]
-
- diag_list.append(Diagnostic(severity, loc, spelling, ranges, fixits))
+_clang_getDiagnosticFixIt = lib.clang_getDiagnosticFixIt
+_clang_getDiagnosticFixIt.argtypes = [c_object_p, c_uint, POINTER(SourceRange)]
+_clang_getDiagnosticFixIt.restype = _CXString
+_clang_getDiagnosticFixIt.errcheck = _CXString.from_result
###
@@ -645,18 +640,14 @@ class Index(ClangObject):
Parameters:
excludeDecls -- Exclude local declarations from translation units.
"""
- return Index(Index_create(excludeDecls))
+ return Index(Index_create(excludeDecls, 0))
def __del__(self):
Index_dispose(self)
def read(self, path):
"""Load the translation unit from the given AST file."""
- # FIXME: In theory, we could support streaming diagnostics. It's hard to
- # integrate this into the API cleanly, however. Resolve.
- diags = []
- ptr = TranslationUnit_read(self, path,
- Diagnostic_callback(_convert_diag), diags)
+ ptr = TranslationUnit_read(self, path)
return TranslationUnit(ptr) if ptr else None
def parse(self, path, args = [], unsaved_files = []):
@@ -687,13 +678,9 @@ class Index(ClangObject):
unsaved_files_array[i].name = name
unsaved_files_array[i].contents = value
unsaved_files_array[i].length = len(value)
- # FIXME: In theory, we could support streaming diagnostics. It's hard to
- # integrate this into the API cleanly, however. Resolve.
- diags = []
ptr = TranslationUnit_parse(self, path, len(args), arg_array,
- len(unsaved_files), unsaved_files_array,
- Diagnostic_callback(_convert_diag), diags)
- return TranslationUnit(ptr, diags) if ptr else None
+ len(unsaved_files), unsaved_files_array)
+ return TranslationUnit(ptr) if ptr else None
class TranslationUnit(ClangObject):
@@ -702,9 +689,8 @@ class TranslationUnit(ClangObject):
provides read-only access to its top-level declarations.
"""
- def __init__(self, ptr, diagnostics):
+ def __init__(self, ptr):
ClangObject.__init__(self, ptr)
- self.diagnostics = diagnostics
def __del__(self):
TranslationUnit_dispose(self)
@@ -738,6 +724,26 @@ class TranslationUnit(ClangObject):
includes)
return iter(includes)
+ @property
+ def diagnostics(self):
+ """
+ Return an iterable (and indexable) object containing the diagnostics.
+ """
+ class DiagIterator:
+ def __init__(self, tu):
+ self.tu = tu
+
+ def __len__(self):
+ return int(_clang_getNumDiagnostics(self.tu))
+
+ def __getitem__(self, key):
+ diag = _clang_getDiagnostic(self.tu, key)
+ if not diag:
+ raise IndexError
+ return Diagnostic(diag)
+
+ return DiagIterator(self)
+
class File(ClangObject):
"""
The File class represents a particular source file that is part of a
@@ -876,24 +882,20 @@ Cursor_visit.restype = c_uint
# Index Functions
Index_create = lib.clang_createIndex
-Index_create.argtypes = [c_int]
+Index_create.argtypes = [c_int, c_int]
Index_create.restype = c_object_p
Index_dispose = lib.clang_disposeIndex
Index_dispose.argtypes = [Index]
# Translation Unit Functions
-Diagnostic_callback = CFUNCTYPE(None, c_object_p, py_object)
-
TranslationUnit_read = lib.clang_createTranslationUnit
-TranslationUnit_read.argtypes = [Index, c_char_p,
- Diagnostic_callback, py_object]
+TranslationUnit_read.argtypes = [Index, c_char_p]
TranslationUnit_read.restype = c_object_p
TranslationUnit_parse = lib.clang_createTranslationUnitFromSourceFile
TranslationUnit_parse.argtypes = [Index, c_char_p, c_int, c_void_p,
- c_int, c_void_p,
- Diagnostic_callback, py_object]
+ c_int, c_void_p]
TranslationUnit_parse.restype = c_object_p
TranslationUnit_cursor = lib.clang_getTranslationUnitCursor
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 7bc290d..da186f6 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -888,6 +888,12 @@ CINDEX_LINKAGE unsigned clang_isInvalid(enum CXCursorKind);
*/
CINDEX_LINKAGE unsigned clang_isTranslationUnit(enum CXCursorKind);
+/***
+ * \brief Determine whether the given cursor represents a currently
+ * unexposed piece of the AST (e.g., CXCursor_UnexposedStmt).
+ */
+CINDEX_LINKAGE unsigned clang_isUnexposed(enum CXCursorKind);
+
/**
* \brief Describe the linkage of the entity referred to by a cursor.
*/
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 0838a3d..cf9aa50 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -405,6 +405,8 @@ private:
/// getExtQualType - Return a type with extended qualifiers.
QualType getExtQualType(const Type *Base, Qualifiers Quals);
+ QualType getTypeDeclTypeSlow(const TypeDecl *Decl);
+
public:
/// getAddSpaceQualType - Return the uniqued reference to the type for an
/// address space qualified type with the specified type and address space.
@@ -580,12 +582,26 @@ public:
/// getTypeDeclType - Return the unique reference to the type for
/// the specified type declaration.
- QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl* PrevDecl=0);
+ QualType getTypeDeclType(const TypeDecl *Decl,
+ const TypeDecl *PrevDecl = 0) {
+ assert(Decl && "Passed null for Decl param");
+ if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
+
+ if (PrevDecl) {
+ assert(PrevDecl->TypeForDecl && "previous decl has no TypeForDecl");
+ Decl->TypeForDecl = PrevDecl->TypeForDecl;
+ return QualType(PrevDecl->TypeForDecl, 0);
+ }
+
+ return getTypeDeclTypeSlow(Decl);
+ }
/// getTypedefType - Return the unique reference to the type for the
/// specified typename decl.
QualType getTypedefType(const TypedefDecl *Decl);
+ QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST);
+
QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
QualType Replacement);
@@ -602,6 +618,11 @@ public:
const TemplateArgumentListInfo &Args,
QualType Canon = QualType());
+ TypeSourceInfo *
+ getTemplateSpecializationTypeInfo(TemplateName T, SourceLocation TLoc,
+ const TemplateArgumentListInfo &Args,
+ QualType Canon = QualType());
+
QualType getQualifiedNameType(NestedNameSpecifier *NNS,
QualType NamedType);
QualType getTypenameType(NestedNameSpecifier *NNS,
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 91aeff3..bd9f01b 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -1429,7 +1429,6 @@ class TypeDecl : public NamedDecl {
friend class DeclContext;
friend class TagDecl;
friend class TemplateTypeParmDecl;
- friend class ClassTemplateSpecializationDecl;
friend class TagType;
protected:
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 26656bf..889e0d6 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -136,8 +136,12 @@ private:
/// in, inout, etc.
unsigned objcDeclQualifier : 6;
- // Type of this method.
+ // Result type of this method.
QualType MethodDeclType;
+
+ // Type source information for the result type.
+ TypeSourceInfo *ResultTInfo;
+
/// ParamInfo - List of pointers to VarDecls for the formal parameters of this
/// Method.
ObjCList<ParmVarDecl> ParamInfo;
@@ -158,6 +162,7 @@ private:
ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
Selector SelInfo, QualType T,
+ TypeSourceInfo *ResultTInfo,
DeclContext *contextDecl,
bool isInstance = true,
bool isVariadic = false,
@@ -168,7 +173,7 @@ private:
IsInstance(isInstance), IsVariadic(isVariadic),
IsSynthesized(isSynthesized),
DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
- MethodDeclType(T),
+ MethodDeclType(T), ResultTInfo(ResultTInfo),
EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {}
virtual ~ObjCMethodDecl() {}
@@ -186,7 +191,9 @@ public:
static ObjCMethodDecl *Create(ASTContext &C,
SourceLocation beginLoc,
SourceLocation endLoc, Selector SelInfo,
- QualType T, DeclContext *contextDecl,
+ QualType T,
+ TypeSourceInfo *ResultTInfo,
+ DeclContext *contextDecl,
bool isInstance = true,
bool isVariadic = false,
bool isSynthesized = false,
@@ -220,6 +227,9 @@ public:
QualType getResultType() const { return MethodDeclType; }
void setResultType(QualType T) { MethodDeclType = T; }
+ TypeSourceInfo *getResultTypeSourceInfo() const { return ResultTInfo; }
+ void setResultTypeSourceInfo(TypeSourceInfo *TInfo) { ResultTInfo = TInfo; }
+
// Iterator access to formal parameters.
unsigned param_size() const { return ParamInfo.size(); }
typedef ObjCList<ParmVarDecl>::iterator param_iterator;
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index ced1747..560ce46 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -771,6 +771,10 @@ class ClassTemplateSpecializationDecl
llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
SpecializedTemplate;
+ /// \brief The type-as-written of an explicit template specialization.
+ /// Does not apply to implicit specializations.
+ TypeSourceInfo *TypeAsWritten;
+
/// \brief The template arguments used to describe this specialization.
TemplateArgumentList TemplateArgs;
@@ -883,8 +887,14 @@ public:
/// \brief Sets the type of this specialization as it was written by
/// the user. This will be a class template specialization type.
- void setTypeAsWritten(QualType T) {
- TypeForDecl = T.getTypePtr();
+ void setTypeAsWritten(TypeSourceInfo *T) {
+ TypeAsWritten = T;
+ }
+
+ /// \brief Gets the type of this specialization as it was written by
+ /// the user, if it was so written.
+ TypeSourceInfo *getTypeAsWritten() const {
+ return TypeAsWritten;
}
void Profile(llvm::FoldingSetNodeID &ID) const {
@@ -921,6 +931,7 @@ class ClassTemplatePartialSpecializationDecl
TemplateParameterList* TemplateParams;
/// \brief The source info for the template arguments as written.
+ /// FIXME: redundant with TypeAsWritten?
TemplateArgumentLoc *ArgsAsWritten;
unsigned NumArgsAsWritten;
@@ -954,6 +965,7 @@ public:
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
const TemplateArgumentListInfo &ArgInfos,
+ QualType CanonInjectedType,
ClassTemplatePartialSpecializationDecl *PrevDecl);
/// Get the list of template parameters
@@ -1139,8 +1151,8 @@ public:
/// the type \p T, or NULL if no such partial specialization exists.
ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
- /// \brief Retrieve the type of the injected-class-name for this
- /// class template.
+ /// \brief Retrieve the template specialization type of the
+ /// injected-class-name for this class template.
///
/// The injected-class-name for a class template \c X is \c
/// X<template-args>, where \c template-args is formed from the
@@ -1153,7 +1165,7 @@ public:
/// typedef array this_type; // "array" is equivalent to "array<T, N>"
/// };
/// \endcode
- QualType getInjectedClassNameType(ASTContext &Context);
+ QualType getInjectedClassNameSpecialization(ASTContext &Context);
/// \brief Retrieve the member class template that this class template was
/// derived from.
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index df39b53..6f43973 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -347,6 +347,9 @@ class ObjCMessageExpr : public Expr {
// message expression.
unsigned NumArgs;
+ /// \brief The location of the class name in a class message.
+ SourceLocation ClassNameLoc;
+
// A unigue name for this message.
Selector SelName;
@@ -367,7 +370,8 @@ class ObjCMessageExpr : public Expr {
public:
/// This constructor is used to represent class messages where the
/// ObjCInterfaceDecl* of the receiver is not known.
- ObjCMessageExpr(ASTContext &C, IdentifierInfo *clsName, Selector selInfo,
+ ObjCMessageExpr(ASTContext &C, IdentifierInfo *clsName,
+ SourceLocation clsNameLoc, Selector selInfo,
QualType retType, ObjCMethodDecl *methDecl,
SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs, unsigned NumArgs);
@@ -375,7 +379,8 @@ public:
/// This constructor is used to represent class messages where the
/// ObjCInterfaceDecl* of the receiver is known.
// FIXME: clsName should be typed to ObjCInterfaceType
- ObjCMessageExpr(ASTContext &C, ObjCInterfaceDecl *cls, Selector selInfo,
+ ObjCMessageExpr(ASTContext &C, ObjCInterfaceDecl *cls,
+ SourceLocation clsNameLoc, Selector selInfo,
QualType retType, ObjCMethodDecl *methDecl,
SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs, unsigned NumArgs);
@@ -411,7 +416,24 @@ public:
ObjCMethodDecl *getMethodDecl() { return MethodProto; }
void setMethodDecl(ObjCMethodDecl *MD) { MethodProto = MD; }
- typedef std::pair<ObjCInterfaceDecl*, IdentifierInfo*> ClassInfo;
+ /// \brief Describes the class receiver of a message send.
+ struct ClassInfo {
+ /// \brief The interface declaration for the class that is
+ /// receiving the message. May be NULL.
+ ObjCInterfaceDecl *Decl;
+
+ /// \brief The name of the class that is receiving the
+ /// message. This will never be NULL.
+ IdentifierInfo *Name;
+
+ /// \brief The source location of the class name.
+ SourceLocation Loc;
+
+ ClassInfo() : Decl(0), Name(0), Loc() { }
+
+ ClassInfo(ObjCInterfaceDecl *Decl, IdentifierInfo *Name, SourceLocation Loc)
+ : Decl(Decl), Name(Name), Loc(Loc) { }
+ };
/// getClassInfo - For class methods, this returns both the ObjCInterfaceDecl*
/// and IdentifierInfo* of the invoked class. Both can be NULL if this
@@ -423,7 +445,7 @@ public:
/// getClassName - For class methods, this returns the invoked class,
/// and returns NULL otherwise. For instance methods, use getReceiver.
IdentifierInfo *getClassName() const {
- return getClassInfo().second;
+ return getClassInfo().Name;
}
/// getNumArgs - Return the number of actual arguments to this call.
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
index 0635ec5..587b5c2 100644
--- a/include/clang/AST/PrettyPrinter.h
+++ b/include/clang/AST/PrettyPrinter.h
@@ -36,7 +36,7 @@ struct PrintingPolicy {
/// \brief Create a default printing policy for C.
PrintingPolicy(const LangOptions &LO)
: Indentation(2), LangOpts(LO), SuppressSpecifiers(false),
- SuppressTag(false), SuppressTagKind(false), SuppressScope(false),
+ SuppressTag(false), SuppressScope(false),
Dump(false), ConstantArraySizeAsWritten(false) { }
/// \brief The number of spaces to use to indent each line.
@@ -71,10 +71,6 @@ struct PrintingPolicy {
/// \endcode
bool SuppressTag : 1;
- /// \brief If we are printing a tag type, suppresses printing of the
- /// kind of tag, e.g., "struct", "union", "enum".
- bool SuppressTagKind : 1;
-
/// \brief Suppresses printing of scope specifiers.
bool SuppressScope : 1;
@@ -101,6 +97,7 @@ struct PrintingPolicy {
/// char a[9] = "A string";
/// \endcode
bool ConstantArraySizeAsWritten : 1;
+
};
} // end namespace clang
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
index e8d1788..cd25969 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -128,47 +128,24 @@ private:
friend class ASTContext;
friend class ASTRecordLayoutBuilder;
- ASTRecordLayout(uint64_t size, unsigned alignment, unsigned datasize,
- const uint64_t *fieldoffsets, unsigned fieldcount)
- : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
- FieldCount(fieldcount), CXXInfo(0) {
- if (FieldCount > 0) {
- FieldOffsets = new uint64_t[FieldCount];
- for (unsigned i = 0; i < FieldCount; ++i)
- FieldOffsets[i] = fieldoffsets[i];
- }
- }
+ ASTRecordLayout(ASTContext &Ctx, uint64_t size, unsigned alignment,
+ unsigned datasize, const uint64_t *fieldoffsets,
+ unsigned fieldcount);
// Constructor for C++ records.
- ASTRecordLayout(uint64_t size, unsigned alignment, uint64_t datasize,
+ ASTRecordLayout(ASTContext &Ctx,
+ uint64_t size, unsigned alignment, uint64_t datasize,
const uint64_t *fieldoffsets, unsigned fieldcount,
uint64_t nonvirtualsize, unsigned nonvirtualalign,
const PrimaryBaseInfo &PrimaryBase,
const std::pair<const CXXRecordDecl *, uint64_t> *bases,
unsigned numbases,
const std::pair<const CXXRecordDecl *, uint64_t> *vbases,
- unsigned numvbases)
- : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
- FieldCount(fieldcount), CXXInfo(new CXXRecordLayoutInfo) {
- if (FieldCount > 0) {
- FieldOffsets = new uint64_t[FieldCount];
- for (unsigned i = 0; i < FieldCount; ++i)
- FieldOffsets[i] = fieldoffsets[i];
- }
+ unsigned numvbases);
- CXXInfo->PrimaryBase = PrimaryBase;
- CXXInfo->NonVirtualSize = nonvirtualsize;
- CXXInfo->NonVirtualAlign = nonvirtualalign;
- for (unsigned i = 0; i != numbases; ++i)
- CXXInfo->BaseOffsets[bases[i].first] = bases[i].second;
- for (unsigned i = 0; i != numvbases; ++i)
- CXXInfo->VBaseOffsets[vbases[i].first] = vbases[i].second;
- }
+ ~ASTRecordLayout() {}
- ~ASTRecordLayout() {
- delete [] FieldOffsets;
- delete CXXInfo;
- }
+ void Destroy(ASTContext &Ctx);
ASTRecordLayout(const ASTRecordLayout&); // DO NOT IMPLEMENT
void operator=(const ASTRecordLayout&); // DO NOT IMPLEMENT
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index bd8a6bc..111be55 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -2440,6 +2440,47 @@ public:
static bool classof(const TemplateSpecializationType *T) { return true; }
};
+/// \brief The injected class name of a C++ class template. Used to
+/// record that a type was spelled with a bare identifier rather than
+/// as a template-id; the equivalent for non-templated classes is just
+/// RecordType.
+///
+/// For consistency, template instantiation turns these into RecordTypes.
+///
+/// The desugared form is always a unqualified TemplateSpecializationType.
+/// The canonical form is always either a TemplateSpecializationType
+/// (when dependent) or a RecordType (otherwise).
+class InjectedClassNameType : public Type {
+ CXXRecordDecl *Decl;
+
+ QualType UnderlyingType;
+
+ friend class ASTContext; // ASTContext creates these.
+ InjectedClassNameType(CXXRecordDecl *D, QualType TST, QualType Canon)
+ : Type(InjectedClassName, Canon, Canon->isDependentType()),
+ Decl(D), UnderlyingType(TST) {
+ assert(isa<TemplateSpecializationType>(TST));
+ assert(!TST.hasQualifiers());
+ assert(TST->getCanonicalTypeInternal() == Canon);
+ }
+
+public:
+ QualType getUnderlyingType() const { return UnderlyingType; }
+ const TemplateSpecializationType *getUnderlyingTST() const {
+ return cast<TemplateSpecializationType>(UnderlyingType.getTypePtr());
+ }
+
+ CXXRecordDecl *getDecl() const { return Decl; }
+
+ bool isSugared() const { return true; }
+ QualType desugar() const { return UnderlyingType; }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == InjectedClassName;
+ }
+ static bool classof(const InjectedClassNameType *T) { return true; }
+};
+
/// \brief Represents a type that was referred to via a qualified
/// name, e.g., N::M::type.
///
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 6fb51ed..27659bd 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -488,6 +488,14 @@ public:
}
};
+/// \brief Wrapper for source info for injected class names of class
+/// templates.
+class InjectedClassNameTypeLoc :
+ public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ InjectedClassNameTypeLoc,
+ InjectedClassNameType> {
+};
+
/// \brief Wrapper for source info for unresolved typename using decls.
class UnresolvedUsingTypeLoc :
public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index 8187cad..e75202e 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -91,6 +91,7 @@ DEPENDENT_TYPE(TemplateTypeParm, Type)
NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
NON_CANONICAL_TYPE(QualifiedName, Type)
+NON_CANONICAL_TYPE(InjectedClassName, Type)
DEPENDENT_TYPE(Typename, Type)
TYPE(ObjCInterface, Type)
TYPE(ObjCObjectPointer, Type)
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index 5d80528..880b4ba 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -284,6 +284,9 @@ BUILTIN(__builtin_ia32_roundps, "V4fV4fi", "")
BUILTIN(__builtin_ia32_roundss, "V4fV4fV4fi", "")
BUILTIN(__builtin_ia32_roundsd, "V2dV2dV2di", "")
BUILTIN(__builtin_ia32_roundpd, "V2dV2di", "")
+BUILTIN(__builtin_ia32_dpps, "V4fV4fV4fi", "")
+BUILTIN(__builtin_ia32_dppd, "V2dV2dV2di", "")
+BUILTIN(__builtin_ia32_movntdqa, "V2LLiV2LLi*", "")
#undef BUILTIN
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index 9175bef..2bce12d 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -90,6 +90,7 @@ def warn_drv_missing_resource_library : Warning<
def warn_drv_conflicting_deployment_targets : Warning<
"conflicting deployment targets, both MACOSX_DEPLOYMENT_TARGET '%0' and IPHONEOS_DEPLOYMENT_TARGET '%1' are present in environment">;
def warn_drv_treating_input_as_cxx : Warning<
- "treating '%0' input as '%1' when in C++ mode, this behavior is deprecated">;
+ "treating '%0' input as '%1' when in C++ mode, this behavior is deprecated">,
+ InGroup<Deprecated>;
}
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index c3c0cf5..17bad64 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -24,7 +24,6 @@ def AddressOfTemporary : DiagGroup<"address-of-temporary">;
def : DiagGroup<"aggregate-return">;
def : DiagGroup<"attributes">;
def : DiagGroup<"bad-function-cast">;
-def BadLiteral : DiagGroup<"bad-literal">;
def : DiagGroup<"c++-compat">;
def : DiagGroup<"cast-align">;
def : DiagGroup<"cast-qual">;
@@ -32,6 +31,7 @@ def : DiagGroup<"char-align">;
def Comment : DiagGroup<"comment">;
def : DiagGroup<"ctor-dtor-privacy">;
def : DiagGroup<"declaration-after-statement">;
+def Deprecated : DiagGroup<"deprecated">;
def : DiagGroup<"disabled-optimization">;
def : DiagGroup<"discard-qual">;
def : DiagGroup<"div-by-zero">;
@@ -48,7 +48,8 @@ def : DiagGroup<"init-self">;
def : DiagGroup<"inline">;
def : DiagGroup<"int-to-pointer-cast">;
def : DiagGroup<"invalid-pch">;
-def : DiagGroup<"missing-braces">;
+def LiteralRange : DiagGroup<"literal-range">;
+def MissingBraces : DiagGroup<"missing-braces">;
def : DiagGroup<"missing-declarations">;
def : DiagGroup<"missing-format-attribute">;
def : DiagGroup<"missing-include-dirs">;
@@ -156,6 +157,7 @@ def Most : DiagGroup<"most", [
Format,
Implicit,
MismatchedTags,
+ MissingBraces,
MultiChar,
ReturnType,
Switch,
@@ -181,4 +183,4 @@ def : DiagGroup<"comments", [Comment]>; // -Wcomments = -Wcomment
// A warning group for warnings that we want to have on by default in clang,
// but which aren't on by default in GCC.
def NonGCC : DiagGroup<"non-gcc",
- [SignCompare, Conversion, BadLiteral]>;
+ [SignCompare, Conversion, LiteralRange]>;
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index fb80dcc..80a4eae 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -159,13 +159,13 @@ def err_typename_invalid_functionspec : Error<
def err_invalid_decl_spec_combination : Error<
"cannot combine with previous '%0' declaration specifier">;
def err_invalid_vector_decl_spec_combination : Error<
- "cannot combine with previous '%0' declaration specifier. \"__vector\" must be first">;
+ "cannot combine with previous '%0' declaration specifier. '__vector' must be first">;
def err_invalid_pixel_decl_spec_combination : Error<
- "\"__pixel\" must be preceded by \"__vector\". '%0' declaration specifier not allowed here">;
+ "'__pixel' must be preceded by '__vector'. '%0' declaration specifier not allowed here">;
def err_invalid_vector_double_decl_spec_combination : Error<
- "cannot use \"double\" with \"__vector\"">;
+ "cannot use 'double' with '__vector'">;
def warn_vector_long_decl_spec_combination : Warning<
- "Use of \"long\" with \"__vector\" is deprecated">;
+ "Use of 'long' with '__vector' is deprecated">, InGroup<Deprecated>;
def err_friend_invalid_in_context : Error<
"'friend' used outside of class">;
def err_unknown_typename : Error<
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index badd64c..13ac9ec 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -31,10 +31,10 @@ def ext_predef_outside_function : Warning<
"predefined identifier is only valid inside function">;
def warn_float_overflow : Warning<
"magnitude of floating-point constant too large for type %0; maximum is %1">,
- InGroup<BadLiteral>;
+ InGroup<LiteralRange>;
def warn_float_underflow : Warning<
"magnitude of floating-point constant too small for type %0; minimum is %1">,
- InGroup<BadLiteral>;
+ InGroup<LiteralRange>;
// C99 Designated Initializers
def err_array_designator_negative : Error<
@@ -141,7 +141,8 @@ def err_using_decl_conflict_reverse : Error<
def note_using_decl : Note<"%select{|previous }0using declaration">;
def warn_access_decl_deprecated : Warning<
- "access declarations are deprecated; use using declarations instead">;
+ "access declarations are deprecated; use using declarations instead">,
+ InGroup<Deprecated>;
def err_invalid_thread : Error<
"'__thread' is only allowed on variable declarations">;
@@ -1580,6 +1581,9 @@ def err_bitfield_width_exceeds_type_size : Error<
"size of bit-field %0 exceeds size of its type (%1 bits)">;
def err_anon_bitfield_width_exceeds_type_size : Error<
"size of anonymous bit-field exceeds size of its type (%0 bits)">;
+def warn_missing_braces : Warning<
+ "suggest braces around initialization of subobject">,
+ InGroup<DiagGroup<"missing-braces">>, DefaultIgnore;
def err_redefinition_of_label : Error<"redefinition of label '%0'">;
def err_undeclared_label_use : Error<"use of undeclared label '%0'">;
@@ -1785,7 +1789,7 @@ def err_array_init_not_init_list : Error<
"array initializer must be an initializer "
"list%select{| or string literal}0">;
def warn_deprecated_string_literal_conversion : Warning<
- "conversion from string literal to %0 is deprecated">;
+ "conversion from string literal to %0 is deprecated">, InGroup<Deprecated>;
def err_realimag_invalid_type : Error<"invalid type %0 to %1 operator">;
def err_typecheck_sclass_fscope : Error<
"illegal storage class on file-scoped variable">;
@@ -2043,11 +2047,11 @@ def note_delete_member_function_declared_here : Note<
"%0 declared here">;
def err_decrement_bool : Error<"cannot decrement expression of type bool">;
def warn_increment_bool : Warning<
- "incrementing expression of type bool is deprecated">;
-def err_catch_incomplete_ptr : Error<
- "cannot catch pointer to incomplete type %0">;
-def err_catch_incomplete_ref : Error<
- "cannot catch reference to incomplete type %0">;
+ "incrementing expression of type bool is deprecated">, InGroup<Deprecated>;
+def ext_catch_incomplete_ptr : ExtWarn<
+ "ISO C++ forbids catching a pointer to incomplete type %0">;
+def ext_catch_incomplete_ref : ExtWarn<
+ "ISO C++ forbids catching a reference to incomplete type %0">;
def err_catch_incomplete : Error<"cannot catch incomplete type %0">;
def err_catch_rvalue_ref : Error<"cannot catch exceptions by rvalue reference">;
def err_qualified_catch_declarator : Error<
diff --git a/include/clang/Checker/PathSensitive/SVals.h b/include/clang/Checker/PathSensitive/SVals.h
index 65a8a2c..040db83 100644
--- a/include/clang/Checker/PathSensitive/SVals.h
+++ b/include/clang/Checker/PathSensitive/SVals.h
@@ -112,6 +112,9 @@ public:
/// wraps a symbol, return that SymbolRef. Otherwise return a SymbolData*
SymbolRef getAsLocSymbol() const;
+ /// Get the symbol in the SVal or its base region.
+ SymbolRef getLocSymbolInBase() const;
+
/// getAsSymbol - If this Sval wraps a symbol return that SymbolRef.
/// Otherwise return a SymbolRef where 'isValid()' returns false.
SymbolRef getAsSymbol() const;
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index 1be4118..828e9b5 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -439,11 +439,11 @@ public:
/// \param OS - The output stream, which should be non-null.
void addOutputFile(llvm::StringRef Path, llvm::raw_ostream *OS);
- /// ClearOutputFiles - Clear the output file list, destroying the contained
+ /// clearOutputFiles - Clear the output file list, destroying the contained
/// output streams.
///
/// \param EraseFiles - If true, attempt to erase the files from disk.
- void ClearOutputFiles(bool EraseFiles);
+ void clearOutputFiles(bool EraseFiles);
/// }
/// @name Construction Utility Methods
diff --git a/include/clang/Frontend/DeclXML.def b/include/clang/Frontend/DeclXML.def
index c750492..e839a8c 100644
--- a/include/clang/Frontend/DeclXML.def
+++ b/include/clang/Frontend/DeclXML.def
@@ -103,7 +103,7 @@ NODE_XML(FunctionDecl, "Function")
//ATTRIBUTE_OPT_XML(isVariadic(), "variadic") // in the type reference
ATTRIBUTE_XML(getNumParams(), "num_args")
SUB_NODE_SEQUENCE_XML(ParmVarDecl)
- //SUB_NODE_OPT_XML("Body")
+ SUB_NODE_FN_BODY_XML
END_NODE_XML
NODE_XML(CXXMethodDecl, "CXXMethodDecl")
@@ -118,13 +118,9 @@ NODE_XML(CXXMethodDecl, "CXXMethodDecl")
ATTRIBUTE_OPT_XML(isVirtual(), "virtual")
ATTRIBUTE_XML(getNumParams(), "num_args")
SUB_NODE_SEQUENCE_XML(ParmVarDecl)
- //SUB_NODE_OPT_XML("Body")
+ SUB_NODE_FN_BODY_XML
END_NODE_XML
-//NODE_XML("Body")
-// SUB_NODE_XML(Stmt)
-//END_NODE_XML
-
NODE_XML(NamespaceDecl, "Namespace")
ID_ATTRIBUTE_XML
ATTRIBUTE_FILE_LOCATION_XML
@@ -156,6 +152,16 @@ NODE_XML(RecordDecl, "Record")
SUB_NODE_SEQUENCE_XML(FieldDecl)
END_NODE_XML
+NODE_XML(CXXRecordDecl, "CXXRecord")
+ ID_ATTRIBUTE_XML
+ ATTRIBUTE_FILE_LOCATION_XML
+ ATTRIBUTE_XML(getDeclContext(), "context")
+ ATTRIBUTE_XML(getNameAsString(), "name")
+ ATTRIBUTE_OPT_XML(isDefinition() == false, "forward")
+ ATTRIBUTE_XML(getTypeForDecl(), "type") // refers to the type this decl creates
+ SUB_NODE_SEQUENCE_XML(FieldDecl)
+END_NODE_XML
+
NODE_XML(EnumDecl, "Enum")
ID_ATTRIBUTE_XML
ATTRIBUTE_FILE_LOCATION_XML
@@ -248,3 +254,4 @@ END_NODE_XML
#undef SUB_NODE_XML
#undef SUB_NODE_SEQUENCE_XML
#undef SUB_NODE_OPT_XML
+#undef SUB_NODE_FN_BODY_XML
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h
index d4014b3..e234e98 100644
--- a/include/clang/Frontend/PCHBitCodes.h
+++ b/include/clang/Frontend/PCHBitCodes.h
@@ -408,7 +408,9 @@ namespace clang {
/// \brief A SubstTemplateTypeParmType record.
TYPE_SUBST_TEMPLATE_TYPE_PARM = 25,
/// \brief An UnresolvedUsingType record.
- TYPE_UNRESOLVED_USING = 26
+ TYPE_UNRESOLVED_USING = 26,
+ /// \brief An InjectedClassNameType record.
+ TYPE_INJECTED_CLASS_NAME = 27
};
/// \brief The type IDs for special types constructed by semantic
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index db9c884..532d8e4 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -43,7 +43,7 @@ class ScratchBuffer;
class TargetInfo;
class PPCallbacks;
class DirectoryLookup;
-
+
/// Preprocessor - This object engages in a tight little dance with the lexer to
/// efficiently preprocess tokens. Lexers know only about tokens within a
/// single source file, and don't know anything about preprocessor-level issues
@@ -60,7 +60,7 @@ class Preprocessor {
/// \brief External source of macros.
ExternalPreprocessorSource *ExternalSource;
-
+
/// PTH - An optional PTHManager object used for getting tokens from
/// a token cache rather than lexing the original source file.
llvm::OwningPtr<PTHManager> PTH;
@@ -105,7 +105,7 @@ class Preprocessor {
/// \brief Whether we have already loaded macros from the external source.
mutable bool ReadMacrosFromExternalSource : 1;
-
+
/// Identifiers - This is mapping/lookup information for all identifiers in
/// the program, including program keywords.
mutable IdentifierTable Identifiers;
@@ -186,7 +186,7 @@ class Preprocessor {
/// allocation.
/// FIXME: why not use a singly linked list?
std::vector<MacroInfo*> MICache;
-
+
/// MacroArgCache - This is a "freelist" of MacroArg objects that can be
/// reused for quick allocation.
MacroArgs *MacroArgCache;
@@ -257,11 +257,11 @@ public:
void setExternalSource(ExternalPreprocessorSource *Source) {
ExternalSource = Source;
}
-
+
ExternalPreprocessorSource *getExternalSource() const {
return ExternalSource;
}
-
+
/// SetCommentRetentionState - Control whether or not the preprocessor retains
/// comments in output.
void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) {
@@ -287,11 +287,11 @@ public:
/// expansions going on at the time.
PreprocessorLexer *getCurrentFileLexer() const;
- /// getPPCallbacks/setPPCallbacks - Accessors for preprocessor callbacks.
+ /// getPPCallbacks/addPPCallbacks - Accessors for preprocessor callbacks.
/// Note that this class takes ownership of any PPCallbacks object given to
/// it.
PPCallbacks *getPPCallbacks() const { return Callbacks; }
- void setPPCallbacks(PPCallbacks *C) {
+ void addPPCallbacks(PPCallbacks *C) {
if (Callbacks)
C = new PPChainedCallbacks(C, Callbacks);
Callbacks = C;
@@ -313,7 +313,7 @@ public:
MacroInfo*>::const_iterator macro_iterator;
macro_iterator macro_begin(bool IncludeExternalMacros = true) const;
macro_iterator macro_end(bool IncludeExternalMacros = true) const;
-
+
const std::string &getPredefines() const { return Predefines; }
/// setPredefines - Set the predefines for this Preprocessor. These
/// predefines are automatically injected when parsing the main file.
@@ -523,7 +523,7 @@ public:
/// (1-based).
///
/// \returns true if an error occurred, false otherwise.
- bool SetCodeCompletionPoint(const FileEntry *File,
+ bool SetCodeCompletionPoint(const FileEntry *File,
unsigned Line, unsigned Column);
/// \brief Determine if this source location refers into the file
diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h
index 4fe81a7..f6f1eb9 100644
--- a/include/clang/Parse/DeclSpec.h
+++ b/include/clang/Parse/DeclSpec.h
@@ -228,7 +228,8 @@ public:
AttrList(0),
ProtocolQualifiers(0),
NumProtocolQualifiers(0),
- ProtocolLocs(0) {
+ ProtocolLocs(0),
+ writtenBS() {
}
~DeclSpec() {
delete AttrList;
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index d8c1c84..26b10b5 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -78,21 +78,21 @@ ASTContext::~ASTContext() {
// Increment in loop to prevent using deallocated memory.
Deallocate(&*I++);
}
- }
- for (llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>::iterator
- I = ASTRecordLayouts.begin(), E = ASTRecordLayouts.end(); I != E; ) {
- // Increment in loop to prevent using deallocated memory.
- ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second);
- delete R;
- }
+ for (llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>::iterator
+ I = ASTRecordLayouts.begin(), E = ASTRecordLayouts.end(); I != E; ) {
+ // Increment in loop to prevent using deallocated memory.
+ if (ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second))
+ R->Destroy(*this);
+ }
- for (llvm::DenseMap<const ObjCContainerDecl*,
- const ASTRecordLayout*>::iterator
- I = ObjCLayouts.begin(), E = ObjCLayouts.end(); I != E; ) {
- // Increment in loop to prevent using deallocated memory.
- ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second);
- delete R;
+ for (llvm::DenseMap<const ObjCContainerDecl*,
+ const ASTRecordLayout*>::iterator
+ I = ObjCLayouts.begin(), E = ObjCLayouts.end(); I != E; ) {
+ // Increment in loop to prevent using deallocated memory.
+ if (ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second))
+ R->Destroy(*this);
+ }
}
// Destroy nested-name-specifiers.
@@ -888,6 +888,10 @@ ASTContext::getTypeInfo(const Type *T) {
case Type::QualifiedName:
return getTypeInfo(cast<QualifiedNameType>(T)->getNamedType().getTypePtr());
+ case Type::InjectedClassName:
+ return getTypeInfo(cast<InjectedClassNameType>(T)
+ ->getUnderlyingType().getTypePtr());
+
case Type::TemplateSpecialization:
assert(getCanonicalType(T) != T &&
"Cannot request the size of a dependent type");
@@ -1918,38 +1922,71 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray,
return QualType(FTP, 0);
}
+#ifndef NDEBUG
+static bool NeedsInjectedClassNameType(const RecordDecl *D) {
+ if (!isa<CXXRecordDecl>(D)) return false;
+ const CXXRecordDecl *RD = cast<CXXRecordDecl>(D);
+ if (isa<ClassTemplatePartialSpecializationDecl>(RD))
+ return true;
+ if (RD->getDescribedClassTemplate() &&
+ !isa<ClassTemplateSpecializationDecl>(RD))
+ return true;
+ return false;
+}
+#endif
+
+/// getInjectedClassNameType - Return the unique reference to the
+/// injected class name type for the specified templated declaration.
+QualType ASTContext::getInjectedClassNameType(CXXRecordDecl *Decl,
+ QualType TST) {
+ assert(NeedsInjectedClassNameType(Decl));
+ if (Decl->TypeForDecl) {
+ assert(isa<InjectedClassNameType>(Decl->TypeForDecl));
+ } else if (CXXRecordDecl *PrevDecl
+ = cast_or_null<CXXRecordDecl>(Decl->getPreviousDeclaration())) {
+ assert(PrevDecl->TypeForDecl && "previous declaration has no type");
+ Decl->TypeForDecl = PrevDecl->TypeForDecl;
+ assert(isa<InjectedClassNameType>(Decl->TypeForDecl));
+ } else {
+ Decl->TypeForDecl = new (*this, TypeAlignment)
+ InjectedClassNameType(Decl, TST, TST->getCanonicalTypeInternal());
+ Types.push_back(Decl->TypeForDecl);
+ }
+ return QualType(Decl->TypeForDecl, 0);
+}
+
/// getTypeDeclType - Return the unique reference to the type for the
/// specified type declaration.
-QualType ASTContext::getTypeDeclType(const TypeDecl *Decl,
- const TypeDecl* PrevDecl) {
+QualType ASTContext::getTypeDeclTypeSlow(const TypeDecl *Decl) {
assert(Decl && "Passed null for Decl param");
- if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
+ assert(!Decl->TypeForDecl && "TypeForDecl present in slow case");
if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Decl))
return getTypedefType(Typedef);
- else if (isa<TemplateTypeParmDecl>(Decl)) {
- assert(false && "Template type parameter types are always available.");
- } else if (const ObjCInterfaceDecl *ObjCInterface
+
+ if (const ObjCInterfaceDecl *ObjCInterface
= dyn_cast<ObjCInterfaceDecl>(Decl))
return getObjCInterfaceType(ObjCInterface);
+ assert(!isa<TemplateTypeParmDecl>(Decl) &&
+ "Template type parameter types are always available.");
+
if (const RecordDecl *Record = dyn_cast<RecordDecl>(Decl)) {
- if (PrevDecl)
- Decl->TypeForDecl = PrevDecl->TypeForDecl;
- else
- Decl->TypeForDecl = new (*this, TypeAlignment) RecordType(Record);
+ assert(!Record->getPreviousDeclaration() &&
+ "struct/union has previous declaration");
+ assert(!NeedsInjectedClassNameType(Record));
+ Decl->TypeForDecl = new (*this, TypeAlignment) RecordType(Record);
} else if (const EnumDecl *Enum = dyn_cast<EnumDecl>(Decl)) {
- if (PrevDecl)
- Decl->TypeForDecl = PrevDecl->TypeForDecl;
- else
- Decl->TypeForDecl = new (*this, TypeAlignment) EnumType(Enum);
+ assert(!Enum->getPreviousDeclaration() &&
+ "enum has previous declaration");
+ Decl->TypeForDecl = new (*this, TypeAlignment) EnumType(Enum);
} else if (const UnresolvedUsingTypenameDecl *Using =
dyn_cast<UnresolvedUsingTypenameDecl>(Decl)) {
Decl->TypeForDecl = new (*this, TypeAlignment) UnresolvedUsingType(Using);
} else
- assert(false && "TypeDecl without a type?");
+ llvm_unreachable("TypeDecl without a type?");
- if (!PrevDecl) Types.push_back(Decl->TypeForDecl);
+ Types.push_back(Decl->TypeForDecl);
return QualType(Decl->TypeForDecl, 0);
}
@@ -2022,6 +2059,24 @@ QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,
return QualType(TypeParm, 0);
}
+TypeSourceInfo *
+ASTContext::getTemplateSpecializationTypeInfo(TemplateName Name,
+ SourceLocation NameLoc,
+ const TemplateArgumentListInfo &Args,
+ QualType CanonType) {
+ QualType TST = getTemplateSpecializationType(Name, Args, CanonType);
+
+ TypeSourceInfo *DI = CreateTypeSourceInfo(TST);
+ TemplateSpecializationTypeLoc TL
+ = cast<TemplateSpecializationTypeLoc>(DI->getTypeLoc());
+ TL.setTemplateNameLoc(NameLoc);
+ TL.setLAngleLoc(Args.getLAngleLoc());
+ TL.setRAngleLoc(Args.getRAngleLoc());
+ for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
+ TL.setArgLocInfo(i, Args[i].getLocInfo());
+ return DI;
+}
+
QualType
ASTContext::getTemplateSpecializationType(TemplateName Template,
const TemplateArgumentListInfo &Args,
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index 7402b7d..866b7f7 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -56,6 +56,12 @@ static bool ShouldAKA(ASTContext &Context, QualType QT,
QT = cast<QualifiedNameType>(Ty)->desugar();
continue;
}
+
+ // ...or an injected class name...
+ if (isa<InjectedClassNameType>(Ty)) {
+ QT = cast<InjectedClassNameType>(Ty)->desugar();
+ continue;
+ }
// ...or a substituted template type parameter.
if (isa<SubstTemplateTypeParmType>(Ty)) {
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 2bcf07e..d9c0d7b 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -610,6 +610,16 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
break;
}
+ case Type::InjectedClassName: {
+ const InjectedClassNameType *Inj1 = cast<InjectedClassNameType>(T1);
+ const InjectedClassNameType *Inj2 = cast<InjectedClassNameType>(T2);
+ if (!IsStructurallyEquivalent(Context,
+ Inj1->getUnderlyingType(),
+ Inj2->getUnderlyingType()))
+ return false;
+ break;
+ }
+
case Type::Typename: {
const TypenameType *Typename1 = cast<TypenameType>(T1);
const TypenameType *Typename2 = cast<TypenameType>(T2);
@@ -2244,12 +2254,14 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
if (ResultTy.isNull())
return 0;
+ TypeSourceInfo *ResultTInfo = Importer.Import(D->getResultTypeSourceInfo());
+
ObjCMethodDecl *ToMethod
= ObjCMethodDecl::Create(Importer.getToContext(),
Loc,
Importer.Import(D->getLocEnd()),
Name.getObjCSelector(),
- ResultTy, DC,
+ ResultTy, ResultTInfo, DC,
D->isInstanceMethod(),
D->isVariadic(),
D->isSynthesized(),
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index e5bd9b7..2f1a6af 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -4,8 +4,8 @@ add_clang_library(clangAST
APValue.cpp
ASTConsumer.cpp
ASTContext.cpp
- ASTImporter.cpp
ASTDiagnostic.cpp
+ ASTImporter.cpp
AttrImpl.cpp
CXXInheritance.cpp
Decl.cpp
@@ -23,6 +23,7 @@ add_clang_library(clangAST
InheritViz.cpp
NestedNameSpecifier.cpp
ParentMap.cpp
+ RecordLayout.cpp
RecordLayoutBuilder.cpp
Stmt.cpp
StmtDumper.cpp
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 9db6ae1..a949534 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -574,11 +574,22 @@ DeclContext *DeclContext::getPrimaryContext() {
if (DeclKind >= Decl::TagFirst && DeclKind <= Decl::TagLast) {
// If this is a tag type that has a definition or is currently
// being defined, that definition is our primary context.
- if (const TagType *TagT =cast<TagDecl>(this)->TypeForDecl->getAs<TagType>())
- if (TagT->isBeingDefined() ||
- (TagT->getDecl() && TagT->getDecl()->isDefinition()))
- return TagT->getDecl();
- return this;
+ TagDecl *Tag = cast<TagDecl>(this);
+ assert(isa<TagType>(Tag->TypeForDecl) ||
+ isa<InjectedClassNameType>(Tag->TypeForDecl));
+
+ if (TagDecl *Def = Tag->getDefinition())
+ return Def;
+
+ if (!isa<InjectedClassNameType>(Tag->TypeForDecl)) {
+ const TagType *TagTy = cast<TagType>(Tag->TypeForDecl);
+ if (TagTy->isBeingDefined())
+ // FIXME: is it necessarily being defined in the decl
+ // that owns the type?
+ return TagTy->getDecl();
+ }
+
+ return Tag;
}
assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 9b693af..7f4ad34 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -636,11 +636,16 @@ QualType CXXMethodDecl::getThisType(ASTContext &C) const {
assert(isInstance() && "No 'this' for static methods!");
- QualType ClassTy;
- if (ClassTemplateDecl *TD = getParent()->getDescribedClassTemplate())
- ClassTy = TD->getInjectedClassNameType(C);
- else
- ClassTy = C.getTagDeclType(getParent());
+ QualType ClassTy = C.getTypeDeclType(getParent());
+
+ // Aesthetically we prefer not to synthesize a type as the
+ // InjectedClassNameType of a template pattern: injected class names
+ // are printed without template arguments, which might
+ // surprise/confuse/distract our poor users if they didn't
+ // explicitly write one.
+ if (isa<InjectedClassNameType>(ClassTy))
+ ClassTy = cast<InjectedClassNameType>(ClassTy)->getUnderlyingType();
+
ClassTy = C.getQualifiedType(ClassTy,
Qualifiers::fromCVRMask(getTypeQualifiers()));
return C.getPointerType(ClassTy);
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 8decafa..67b71a0 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -304,15 +304,16 @@ ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C,
SourceLocation beginLoc,
SourceLocation endLoc,
Selector SelInfo, QualType T,
+ TypeSourceInfo *ResultTInfo,
DeclContext *contextDecl,
bool isInstance,
bool isVariadic,
bool isSynthesized,
ImplementationControl impControl) {
return new (C) ObjCMethodDecl(beginLoc, endLoc,
- SelInfo, T, contextDecl,
- isInstance,
- isVariadic, isSynthesized, impControl);
+ SelInfo, T, ResultTInfo, contextDecl,
+ isInstance,
+ isVariadic, isSynthesized, impControl);
}
void ObjCMethodDecl::Destroy(ASTContext &C) {
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index d80db45..b449398 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -193,7 +193,8 @@ ClassTemplateDecl::findPartialSpecialization(QualType T) {
return 0;
}
-QualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) {
+QualType
+ClassTemplateDecl::getInjectedClassNameSpecialization(ASTContext &Context) {
if (!CommonPtr->InjectedClassNameType.isNull())
return CommonPtr->InjectedClassNameType;
@@ -393,6 +394,7 @@ ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
SpecializedTemplate->getIdentifier(),
PrevDecl),
SpecializedTemplate(SpecializedTemplate),
+ TypeAsWritten(0),
TemplateArgs(Context, Builder, /*TakeArgs=*/true),
SpecializationKind(TSK_Undeclared) {
}
@@ -453,6 +455,7 @@ Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
ClassTemplateDecl *SpecializedTemplate,
TemplateArgumentListBuilder &Builder,
const TemplateArgumentListInfo &ArgInfos,
+ QualType CanonInjectedType,
ClassTemplatePartialSpecializationDecl *PrevDecl) {
unsigned N = ArgInfos.size();
TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
@@ -467,7 +470,8 @@ Create(ASTContext &Context, DeclContext *DC, SourceLocation L,
ClonedArgs, N,
PrevDecl);
Result->setSpecializationKind(TSK_ExplicitSpecialization);
- Context.getTypeDeclType(Result, PrevDecl);
+
+ Context.getInjectedClassNameType(Result, CanonInjectedType);
return Result;
}
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index a2914bc..efd0fd1 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -181,7 +181,6 @@ std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) {
}
PrintingPolicy Policy(Context.getLangOptions());
- Policy.SuppressTagKind = true;
std::string Proto = FD->getQualifiedNameAsString(Policy);
@@ -2115,12 +2114,12 @@ ObjCMessageExpr::ObjCMessageExpr(ASTContext &C, Expr *receiver,
// constructor for class messages.
// FIXME: clsName should be typed to ObjCInterfaceType
ObjCMessageExpr::ObjCMessageExpr(ASTContext &C, IdentifierInfo *clsName,
- Selector selInfo, QualType retType,
- ObjCMethodDecl *mproto,
+ SourceLocation clsNameLoc, Selector selInfo,
+ QualType retType, ObjCMethodDecl *mproto,
SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs, unsigned nargs)
- : Expr(ObjCMessageExprClass, retType, false, false), SelName(selInfo),
- MethodProto(mproto) {
+ : Expr(ObjCMessageExprClass, retType, false, false), ClassNameLoc(clsNameLoc),
+ SelName(selInfo), MethodProto(mproto) {
NumArgs = nargs;
SubExprs = new (C) Stmt*[NumArgs+1];
SubExprs[RECEIVER] = (Expr*) ((uintptr_t) clsName | IsClsMethDeclUnknown);
@@ -2134,12 +2133,14 @@ ObjCMessageExpr::ObjCMessageExpr(ASTContext &C, IdentifierInfo *clsName,
// constructor for class messages.
ObjCMessageExpr::ObjCMessageExpr(ASTContext &C, ObjCInterfaceDecl *cls,
- Selector selInfo, QualType retType,
+ SourceLocation clsNameLoc, Selector selInfo,
+ QualType retType,
ObjCMethodDecl *mproto, SourceLocation LBrac,
SourceLocation RBrac, Expr **ArgExprs,
unsigned nargs)
-: Expr(ObjCMessageExprClass, retType, false, false), SelName(selInfo),
-MethodProto(mproto) {
+ : Expr(ObjCMessageExprClass, retType, false, false), ClassNameLoc(clsNameLoc),
+ SelName(selInfo), MethodProto(mproto)
+{
NumArgs = nargs;
SubExprs = new (C) Stmt*[NumArgs+1];
SubExprs[RECEIVER] = (Expr*) ((uintptr_t) cls | IsClsMethDeclKnown);
@@ -2157,23 +2158,27 @@ ObjCMessageExpr::ClassInfo ObjCMessageExpr::getClassInfo() const {
default:
assert(false && "Invalid ObjCMessageExpr.");
case IsInstMeth:
- return ClassInfo(0, 0);
+ return ClassInfo(0, 0, SourceLocation());
case IsClsMethDeclUnknown:
- return ClassInfo(0, (IdentifierInfo*) (x & ~Flags));
+ return ClassInfo(0, (IdentifierInfo*) (x & ~Flags), ClassNameLoc);
case IsClsMethDeclKnown: {
ObjCInterfaceDecl* D = (ObjCInterfaceDecl*) (x & ~Flags);
- return ClassInfo(D, D->getIdentifier());
+ return ClassInfo(D, D->getIdentifier(), ClassNameLoc);
}
}
}
void ObjCMessageExpr::setClassInfo(const ObjCMessageExpr::ClassInfo &CI) {
- if (CI.first == 0 && CI.second == 0)
+ if (CI.Decl == 0 && CI.Name == 0) {
SubExprs[RECEIVER] = (Expr*)((uintptr_t)0 | IsInstMeth);
- else if (CI.first == 0)
- SubExprs[RECEIVER] = (Expr*)((uintptr_t)CI.second | IsClsMethDeclUnknown);
+ return;
+ }
+
+ if (CI.Decl == 0)
+ SubExprs[RECEIVER] = (Expr*)((uintptr_t)CI.Name | IsClsMethDeclUnknown);
else
- SubExprs[RECEIVER] = (Expr*)((uintptr_t)CI.first | IsClsMethDeclKnown);
+ SubExprs[RECEIVER] = (Expr*)((uintptr_t)CI.Decl | IsClsMethDeclKnown);
+ ClassNameLoc = CI.Loc;
}
void ObjCMessageExpr::DoDestroy(ASTContext &C) {
diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp
index e26c0bb..45518e9 100644
--- a/lib/AST/NestedNameSpecifier.cpp
+++ b/lib/AST/NestedNameSpecifier.cpp
@@ -142,7 +142,6 @@ NestedNameSpecifier::print(llvm::raw_ostream &OS,
Type *T = getAsType();
PrintingPolicy InnerPolicy(Policy);
- InnerPolicy.SuppressTagKind = true;
InnerPolicy.SuppressScope = true;
// Nested-name-specifiers are intended to contain minimally-qualified
diff --git a/lib/AST/RecordLayout.cpp b/lib/AST/RecordLayout.cpp
new file mode 100644
index 0000000..838753a
--- /dev/null
+++ b/lib/AST/RecordLayout.cpp
@@ -0,0 +1,67 @@
+//===-- RecordLayout.cpp - Layout information for a struct/union -*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the RecordLayout interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecordLayout.h"
+
+using namespace clang;
+
+void ASTRecordLayout::Destroy(ASTContext &Ctx) {
+ if (FieldOffsets)
+ Ctx.Deallocate(FieldOffsets);
+ if (CXXInfo)
+ Ctx.Deallocate(CXXInfo);
+ this->~ASTRecordLayout();
+ Ctx.Deallocate(this);
+}
+
+ASTRecordLayout::ASTRecordLayout(ASTContext &Ctx, uint64_t size, unsigned alignment,
+ unsigned datasize, const uint64_t *fieldoffsets,
+ unsigned fieldcount)
+ : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
+ FieldCount(fieldcount), CXXInfo(0) {
+ if (FieldCount > 0) {
+ FieldOffsets = new (Ctx) uint64_t[FieldCount];
+ memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
+ }
+}
+
+// Constructor for C++ records.
+ASTRecordLayout::ASTRecordLayout(ASTContext &Ctx,
+ uint64_t size, unsigned alignment,
+ uint64_t datasize,
+ const uint64_t *fieldoffsets,
+ unsigned fieldcount,
+ uint64_t nonvirtualsize,
+ unsigned nonvirtualalign,
+ const PrimaryBaseInfo &PrimaryBase,
+ const std::pair<const CXXRecordDecl *, uint64_t> *bases,
+ unsigned numbases,
+ const std::pair<const CXXRecordDecl *, uint64_t> *vbases,
+ unsigned numvbases)
+ : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
+ FieldCount(fieldcount), CXXInfo(new (Ctx) CXXRecordLayoutInfo)
+{
+ if (FieldCount > 0) {
+ FieldOffsets = new (Ctx) uint64_t[FieldCount];
+ memcpy(FieldOffsets, fieldoffsets, FieldCount * sizeof(*FieldOffsets));
+ }
+
+ CXXInfo->PrimaryBase = PrimaryBase;
+ CXXInfo->NonVirtualSize = nonvirtualsize;
+ CXXInfo->NonVirtualAlign = nonvirtualalign;
+ for (unsigned i = 0; i != numbases; ++i)
+ CXXInfo->BaseOffsets[bases[i].first] = bases[i].second;
+ for (unsigned i = 0; i != numvbases; ++i)
+ CXXInfo->VBaseOffsets[vbases[i].first] = vbases[i].second;
+}
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index 10c5089..22285ca 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -675,9 +675,10 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
Builder.Layout(D);
if (!isa<CXXRecordDecl>(D))
- return new ASTRecordLayout(Builder.Size, Builder.Alignment, Builder.Size,
- Builder.FieldOffsets.data(),
- Builder.FieldOffsets.size());
+ return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment,
+ Builder.Size,
+ Builder.FieldOffsets.data(),
+ Builder.FieldOffsets.size());
// FIXME: This is not always correct. See the part about bitfields at
// http://www.codesourcery.com/public/cxx-abi/abi.html#POD for more info.
@@ -690,16 +691,16 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
uint64_t NonVirtualSize =
IsPODForThePurposeOfLayout ? DataSize : Builder.NonVirtualSize;
- return new ASTRecordLayout(Builder.Size, Builder.Alignment, DataSize,
- Builder.FieldOffsets.data(),
- Builder.FieldOffsets.size(),
- NonVirtualSize,
- Builder.NonVirtualAlignment,
- Builder.PrimaryBase,
- Builder.Bases.data(),
- Builder.Bases.size(),
- Builder.VBases.data(),
- Builder.VBases.size());
+ return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment,
+ DataSize, Builder.FieldOffsets.data(),
+ Builder.FieldOffsets.size(),
+ NonVirtualSize,
+ Builder.NonVirtualAlignment,
+ Builder.PrimaryBase,
+ Builder.Bases.data(),
+ Builder.Bases.size(),
+ Builder.VBases.data(),
+ Builder.VBases.size());
}
const ASTRecordLayout *
@@ -710,10 +711,10 @@ ASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
Builder.Layout(D, Impl);
- return new ASTRecordLayout(Builder.Size, Builder.Alignment,
- Builder.DataSize,
- Builder.FieldOffsets.data(),
- Builder.FieldOffsets.size());
+ return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment,
+ Builder.DataSize,
+ Builder.FieldOffsets.data(),
+ Builder.FieldOffsets.size());
}
const CXXMethodDecl *
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 76cc382..8a64f8e 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -650,6 +650,7 @@ bool Type::isPODType() const {
case Vector:
case ExtVector:
case ObjCObjectPointer:
+ case BlockPointer:
return true;
case Enum:
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index 5b621cf..037bc14 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -30,7 +30,8 @@ namespace {
explicit TypePrinter(const PrintingPolicy &Policy) : Policy(Policy) { }
void Print(QualType T, std::string &S);
- void PrintTag(const TagType *T, std::string &S);
+ void AppendScope(DeclContext *DC, std::string &S);
+ void PrintTag(TagDecl *T, std::string &S);
#define ABSTRACT_TYPE(CLASS, PARENT)
#define TYPE(CLASS, PARENT) \
void Print##CLASS(const CLASS##Type *T, std::string &S);
@@ -330,19 +331,21 @@ void TypePrinter::PrintFunctionNoProto(const FunctionNoProtoType *T,
Print(T->getResultType(), S);
}
-void TypePrinter::PrintUnresolvedUsing(const UnresolvedUsingType *T,
- std::string &S) {
- IdentifierInfo *II = T->getDecl()->getIdentifier();
+static void PrintTypeSpec(const NamedDecl *D, std::string &S) {
+ IdentifierInfo *II = D->getIdentifier();
if (S.empty())
S = II->getName().str();
else
S = II->getName().str() + ' ' + S;
}
+void TypePrinter::PrintUnresolvedUsing(const UnresolvedUsingType *T,
+ std::string &S) {
+ PrintTypeSpec(T->getDecl(), S);
+}
+
void TypePrinter::PrintTypedef(const TypedefType *T, std::string &S) {
- if (!S.empty()) // Prefix the basic type, e.g. 'typedefname X'.
- S = ' ' + S;
- S = T->getDecl()->getIdentifier()->getName().str() + S;
+ PrintTypeSpec(T->getDecl(), S);
}
void TypePrinter::PrintTypeOfExpr(const TypeOfExprType *T, std::string &S) {
@@ -371,89 +374,106 @@ void TypePrinter::PrintDecltype(const DecltypeType *T, std::string &S) {
S = "decltype(" + s.str() + ")" + S;
}
-void TypePrinter::PrintTag(const TagType *T, std::string &InnerString) {
+/// Appends the given scope to the end of a string.
+void TypePrinter::AppendScope(DeclContext *DC, std::string &Buffer) {
+ if (DC->isTranslationUnit()) return;
+ AppendScope(DC->getParent(), Buffer);
+
+ unsigned OldSize = Buffer.size();
+
+ if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
+ if (NS->getIdentifier())
+ Buffer += NS->getNameAsString();
+ else
+ Buffer += "<anonymous>";
+ } else if (ClassTemplateSpecializationDecl *Spec
+ = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
+ const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
+ std::string TemplateArgsStr
+ = TemplateSpecializationType::PrintTemplateArgumentList(
+ TemplateArgs.getFlatArgumentList(),
+ TemplateArgs.flat_size(),
+ Policy);
+ Buffer += Spec->getIdentifier()->getName();
+ Buffer += TemplateArgsStr;
+ } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
+ if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl())
+ Buffer += Typedef->getIdentifier()->getName();
+ else if (Tag->getIdentifier())
+ Buffer += Tag->getIdentifier()->getName();
+ }
+
+ if (Buffer.size() != OldSize)
+ Buffer += "::";
+}
+
+void TypePrinter::PrintTag(TagDecl *D, std::string &InnerString) {
if (Policy.SuppressTag)
return;
-
- if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
- InnerString = ' ' + InnerString;
-
- const char *Kind = Policy.SuppressTagKind? 0 : T->getDecl()->getKindName();
+
+ std::string Buffer;
+
+ // We don't print tags unless this is an elaborated type.
+ // In C, we just assume every RecordType is an elaborated type.
+ if (!Policy.LangOpts.CPlusPlus && !D->getTypedefForAnonDecl()) {
+ Buffer += D->getKindName();
+ Buffer += ' ';
+ }
+
+ if (!Policy.SuppressScope)
+ // Compute the full nested-name-specifier for this type. In C,
+ // this will always be empty.
+ AppendScope(D->getDeclContext(), Buffer);
+
const char *ID;
- if (const IdentifierInfo *II = T->getDecl()->getIdentifier())
+ if (const IdentifierInfo *II = D->getIdentifier())
ID = II->getNameStart();
- else if (TypedefDecl *Typedef = T->getDecl()->getTypedefForAnonDecl()) {
- Kind = 0;
+ else if (TypedefDecl *Typedef = D->getTypedefForAnonDecl()) {
assert(Typedef->getIdentifier() && "Typedef without identifier?");
ID = Typedef->getIdentifier()->getNameStart();
} else
ID = "<anonymous>";
-
+ Buffer += ID;
+
// If this is a class template specialization, print the template
// arguments.
if (ClassTemplateSpecializationDecl *Spec
- = dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl())) {
- const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
- std::string TemplateArgsStr
- = TemplateSpecializationType::PrintTemplateArgumentList(
- TemplateArgs.getFlatArgumentList(),
- TemplateArgs.flat_size(),
- Policy);
- InnerString = TemplateArgsStr + InnerString;
- }
-
- if (!Policy.SuppressScope) {
- // Compute the full nested-name-specifier for this type. In C,
- // this will always be empty.
- std::string ContextStr;
- for (DeclContext *DC = T->getDecl()->getDeclContext();
- !DC->isTranslationUnit(); DC = DC->getParent()) {
- std::string MyPart;
- if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(DC)) {
- if (NS->getIdentifier())
- MyPart = NS->getNameAsString();
- } else if (ClassTemplateSpecializationDecl *Spec
- = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
- const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
- std::string TemplateArgsStr
- = TemplateSpecializationType::PrintTemplateArgumentList(
- TemplateArgs.getFlatArgumentList(),
- TemplateArgs.flat_size(),
- Policy);
- MyPart = Spec->getIdentifier()->getName().str() + TemplateArgsStr;
- } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
- if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl())
- MyPart = Typedef->getIdentifier()->getName();
- else if (Tag->getIdentifier())
- MyPart = Tag->getIdentifier()->getName();
- }
-
- if (!MyPart.empty())
- ContextStr = MyPart + "::" + ContextStr;
+ = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
+ const TemplateArgument *Args;
+ unsigned NumArgs;
+ if (TypeSourceInfo *TAW = Spec->getTypeAsWritten()) {
+ const TemplateSpecializationType *TST =
+ cast<TemplateSpecializationType>(TAW->getType());
+ Args = TST->getArgs();
+ NumArgs = TST->getNumArgs();
+ } else {
+ const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
+ Args = TemplateArgs.getFlatArgumentList();
+ NumArgs = TemplateArgs.flat_size();
}
-
- if (Kind)
- InnerString = std::string(Kind) + ' ' + ContextStr + ID + InnerString;
- else
- InnerString = ContextStr + ID + InnerString;
- } else
- InnerString = ID + InnerString;
+ Buffer += TemplateSpecializationType::PrintTemplateArgumentList(Args,
+ NumArgs,
+ Policy);
+ }
+
+ if (!InnerString.empty()) {
+ Buffer += ' ';
+ Buffer += InnerString;
+ }
+
+ std::swap(Buffer, InnerString);
}
void TypePrinter::PrintRecord(const RecordType *T, std::string &S) {
- PrintTag(T, S);
+ PrintTag(T->getDecl(), S);
}
void TypePrinter::PrintEnum(const EnumType *T, std::string &S) {
- PrintTag(T, S);
+ PrintTag(T->getDecl(), S);
}
void TypePrinter::PrintElaborated(const ElaboratedType *T, std::string &S) {
- std::string TypeStr;
- PrintingPolicy InnerPolicy(Policy);
- InnerPolicy.SuppressTagKind = true;
- TypePrinter(InnerPolicy).Print(T->getUnderlyingType(), S);
-
+ Print(T->getUnderlyingType(), S);
S = std::string(T->getNameForTagKind(T->getTagKind())) + ' ' + S;
}
@@ -494,6 +514,11 @@ void TypePrinter::PrintTemplateSpecialization(
S = SpecString + ' ' + S;
}
+void TypePrinter::PrintInjectedClassName(const InjectedClassNameType *T,
+ std::string &S) {
+ PrintTemplateSpecialization(T->getUnderlyingTST(), S);
+}
+
void TypePrinter::PrintQualifiedName(const QualifiedNameType *T,
std::string &S) {
std::string MyString;
@@ -505,7 +530,6 @@ void TypePrinter::PrintQualifiedName(const QualifiedNameType *T,
std::string TypeStr;
PrintingPolicy InnerPolicy(Policy);
- InnerPolicy.SuppressTagKind = true;
InnerPolicy.SuppressScope = true;
TypePrinter(InnerPolicy).Print(T->getNamedType(), TypeStr);
diff --git a/lib/Analysis/AnalysisContext.cpp b/lib/Analysis/AnalysisContext.cpp
index d9933e8..5640c4a 100644
--- a/lib/Analysis/AnalysisContext.cpp
+++ b/lib/Analysis/AnalysisContext.cpp
@@ -12,15 +12,16 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/Analysis/CFG.h"
-#include "clang/Analysis/AnalysisContext.h"
-#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/ParentMap.h"
#include "clang/AST/StmtVisitor.h"
+#include "clang/Analysis/Analyses/LiveVariables.h"
+#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/CFG.h"
#include "clang/Analysis/Support/BumpVector.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/Support/ErrorHandling.h"
using namespace clang;
@@ -207,11 +208,17 @@ class FindBlockDeclRefExprsVals : public StmtVisitor<FindBlockDeclRefExprsVals>{
BumpVector<const VarDecl*> &BEVals;
BumpVectorContext &BC;
llvm::DenseMap<const VarDecl*, unsigned> Visited;
+ llvm::SmallSet<const DeclContext*, 4> IgnoredContexts;
public:
FindBlockDeclRefExprsVals(BumpVector<const VarDecl*> &bevals,
BumpVectorContext &bc)
: BEVals(bevals), BC(bc) {}
-
+
+ bool IsTrackedDecl(const VarDecl *VD) {
+ const DeclContext *DC = VD->getDeclContext();
+ return IgnoredContexts.count(DC) == 0;
+ }
+
void VisitStmt(Stmt *S) {
for (Stmt::child_iterator I = S->child_begin(), E = S->child_end();I!=E;++I)
if (Stmt *child = *I)
@@ -229,16 +236,23 @@ public:
}
}
}
-
+
void VisitBlockDeclRefExpr(BlockDeclRefExpr *DR) {
if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
unsigned &flag = Visited[VD];
if (!flag) {
flag = 1;
- BEVals.push_back(VD, BC);
+ if (IsTrackedDecl(VD))
+ BEVals.push_back(VD, BC);
}
}
}
+
+ void VisitBlockExpr(BlockExpr *BR) {
+ // Blocks containing blocks can transitively capture more variables.
+ IgnoredContexts.insert(BR->getBlockDecl());
+ Visit(BR->getBlockDecl()->getBody());
+ }
};
} // end anonymous namespace
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index ae6d5df..3b226d0 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -598,6 +598,134 @@ public:
} // end anonymous namespace.
namespace {
+// MBlaze abstract base class
+class MBlazeTargetInfo : public TargetInfo {
+ static const char * const GCCRegNames[];
+ static const TargetInfo::GCCRegAlias GCCRegAliases[];
+
+public:
+ MBlazeTargetInfo(const std::string& triple) : TargetInfo(triple) {
+ DescriptionString = "E-p:32:32-i8:8:8-i16:16:16-i64:32:32-f64:32:32-"
+ "v64:32:32-v128:32:32-n32";
+ }
+
+ virtual void getTargetBuiltins(const Builtin::Info *&Records,
+ unsigned &NumRecords) const {
+ // FIXME: Implement.
+ Records = 0;
+ NumRecords = 0;
+ }
+
+ virtual void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const;
+
+ virtual const char *getVAListDeclaration() const {
+ return "typedef char* __builtin_va_list;";
+ }
+ virtual const char *getTargetPrefix() const {
+ return "mblaze";
+ }
+ virtual void getGCCRegNames(const char * const *&Names,
+ unsigned &NumNames) const;
+ virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+ unsigned &NumAliases) const;
+ virtual bool validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &Info) const {
+ switch (*Name) {
+ default: return false;
+ case 'O': // Zero
+ return true;
+ case 'b': // Base register
+ case 'f': // Floating point register
+ Info.setAllowsRegister();
+ return true;
+ }
+ }
+ virtual const char *getClobbers() const {
+ return "";
+ }
+};
+
+/// MBlazeTargetInfo::getTargetDefines - Return a set of the MBlaze-specific
+/// #defines that are not tied to a specific subtarget.
+void MBlazeTargetInfo::getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ // Target identification.
+ Builder.defineMacro("__microblaze__");
+ Builder.defineMacro("_ARCH_MICROBLAZE");
+ Builder.defineMacro("__MICROBLAZE__");
+
+ // Target properties.
+ Builder.defineMacro("_BIG_ENDIAN");
+ Builder.defineMacro("__BIG_ENDIAN__");
+
+ // Subtarget options.
+ Builder.defineMacro("__REGISTER_PREFIX__", "");
+}
+
+
+const char * const MBlazeTargetInfo::GCCRegNames[] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+ "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
+ "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
+ "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
+ "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
+ "hi", "lo", "accum","rmsr", "$fcc1","$fcc2","$fcc3","$fcc4",
+ "$fcc5","$fcc6","$fcc7","$ap", "$rap", "$frp"
+};
+
+void MBlazeTargetInfo::getGCCRegNames(const char * const *&Names,
+ unsigned &NumNames) const {
+ Names = GCCRegNames;
+ NumNames = llvm::array_lengthof(GCCRegNames);
+}
+
+const TargetInfo::GCCRegAlias MBlazeTargetInfo::GCCRegAliases[] = {
+ { {"f0"}, "r0" },
+ { {"f1"}, "r1" },
+ { {"f2"}, "r2" },
+ { {"f3"}, "r3" },
+ { {"f4"}, "r4" },
+ { {"f5"}, "r5" },
+ { {"f6"}, "r6" },
+ { {"f7"}, "r7" },
+ { {"f8"}, "r8" },
+ { {"f9"}, "r9" },
+ { {"f10"}, "r10" },
+ { {"f11"}, "r11" },
+ { {"f12"}, "r12" },
+ { {"f13"}, "r13" },
+ { {"f14"}, "r14" },
+ { {"f15"}, "r15" },
+ { {"f16"}, "r16" },
+ { {"f17"}, "r17" },
+ { {"f18"}, "r18" },
+ { {"f19"}, "r19" },
+ { {"f20"}, "r20" },
+ { {"f21"}, "r21" },
+ { {"f22"}, "r22" },
+ { {"f23"}, "r23" },
+ { {"f24"}, "r24" },
+ { {"f25"}, "r25" },
+ { {"f26"}, "r26" },
+ { {"f27"}, "r27" },
+ { {"f28"}, "r28" },
+ { {"f29"}, "r29" },
+ { {"f30"}, "r30" },
+ { {"f31"}, "r31" },
+};
+
+void MBlazeTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
+ unsigned &NumAliases) const {
+ Aliases = GCCRegAliases;
+ NumAliases = llvm::array_lengthof(GCCRegAliases);
+}
+} // end anonymous namespace.
+
+namespace {
// Namespace for x86 abstract base class
const Builtin::Info BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, false },
@@ -2159,6 +2287,9 @@ static TargetInfo *AllocateTarget(const std::string &T) {
return new FreeBSDTargetInfo<PPC64TargetInfo>(T);
return new PPC64TargetInfo(T);
+ case llvm::Triple::mblaze:
+ return new MBlazeTargetInfo(T);
+
case llvm::Triple::sparc:
if (os == llvm::Triple::AuroraUX)
return new AuroraUXSparcV8TargetInfo(T);
diff --git a/lib/Checker/BasicStore.cpp b/lib/Checker/BasicStore.cpp
index d93a665..10136f3 100644
--- a/lib/Checker/BasicStore.cpp
+++ b/lib/Checker/BasicStore.cpp
@@ -142,7 +142,8 @@ SVal BasicStoreManager::LazyRetrieve(Store store, const TypedRegion *R) {
// Globals and parameters start with symbolic values.
// Local variables initially are undefined.
- if (VR->hasGlobalsOrParametersStorage())
+ if (VR->hasGlobalsOrParametersStorage() ||
+ isa<UnknownSpaceRegion>(VR->getMemorySpace()))
return ValMgr.getRegionValueSymbolVal(R);
return UndefinedVal();
}
diff --git a/lib/Checker/CFRefCount.cpp b/lib/Checker/CFRefCount.cpp
index ecb98a0..9a76f6a 100644
--- a/lib/Checker/CFRefCount.cpp
+++ b/lib/Checker/CFRefCount.cpp
@@ -853,7 +853,7 @@ public:
RetainSummary *getClassMethodSummary(const ObjCMessageExpr *ME) {
return getClassMethodSummary(ME->getSelector(), ME->getClassName(),
- ME->getClassInfo().first,
+ ME->getClassInfo().Decl,
ME->getMethodDecl(), ME->getType());
}
@@ -2511,7 +2511,7 @@ static QualType GetReturnType(const Expr* RetE, ASTContext& Ctx) {
// id, id<...>, or Class. If we have an ObjCInterfaceDecl, we know this
// is a call to a class method whose type we can resolve. In such
// cases, promote the return type to XXX* (where XXX is the class).
- const ObjCInterfaceDecl *D = ME->getClassInfo().first;
+ const ObjCInterfaceDecl *D = ME->getClassInfo().Decl;
return !D ? RetTy : Ctx.getPointerType(Ctx.getObjCInterfaceType(D));
}
diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp
index 2ea689e..130d805 100644
--- a/lib/Checker/GRExprEngine.cpp
+++ b/lib/Checker/GRExprEngine.cpp
@@ -25,7 +25,6 @@
#include "clang/Basic/PrettyStackTrace.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/ImmutableList.h"
-#include "llvm/ADT/StringSwitch.h"
#ifndef NDEBUG
#include "llvm/Support/GraphWriter.h"
diff --git a/lib/Checker/MallocChecker.cpp b/lib/Checker/MallocChecker.cpp
index 4ff9864..a08afc4 100644
--- a/lib/Checker/MallocChecker.cpp
+++ b/lib/Checker/MallocChecker.cpp
@@ -57,17 +57,20 @@ class RegionState {};
class MallocChecker : public CheckerVisitor<MallocChecker> {
BuiltinBug *BT_DoubleFree;
BuiltinBug *BT_Leak;
+ BuiltinBug *BT_UseFree;
IdentifierInfo *II_malloc, *II_free, *II_realloc;
public:
MallocChecker()
- : BT_DoubleFree(0), BT_Leak(0), II_malloc(0), II_free(0), II_realloc(0) {}
+ : BT_DoubleFree(0), BT_Leak(0), BT_UseFree(0),
+ II_malloc(0), II_free(0), II_realloc(0) {}
static void *getTag();
bool EvalCallExpr(CheckerContext &C, const CallExpr *CE);
void EvalDeadSymbols(CheckerContext &C,const Stmt *S,SymbolReaper &SymReaper);
void EvalEndPath(GREndPathNodeBuilder &B, void *tag, GRExprEngine &Eng);
void PreVisitReturnStmt(CheckerContext &C, const ReturnStmt *S);
const GRState *EvalAssume(const GRState *state, SVal Cond, bool Assumption);
+ void VisitLocation(CheckerContext &C, const Stmt *S, SVal l);
private:
void MallocMem(CheckerContext &C, const CallExpr *CE);
@@ -339,3 +342,22 @@ const GRState *MallocChecker::EvalAssume(const GRState *state, SVal Cond,
return state;
}
+
+// Check if the location is a freed symbolic region.
+void MallocChecker::VisitLocation(CheckerContext &C, const Stmt *S, SVal l) {
+ SymbolRef Sym = l.getLocSymbolInBase();
+ if (Sym) {
+ const RefState *RS = C.getState()->get<RegionState>(Sym);
+ if (RS)
+ if (RS->isReleased()) {
+ ExplodedNode *N = C.GenerateSink();
+ if (!BT_UseFree)
+ BT_UseFree = new BuiltinBug("Use dynamically allocated memory after"
+ " it is freed.");
+
+ BugReport *R = new BugReport(*BT_UseFree, BT_UseFree->getDescription(),
+ N);
+ C.EmitReport(R);
+ }
+ }
+}
diff --git a/lib/Checker/RegionStore.cpp b/lib/Checker/RegionStore.cpp
index fd48f72..91c3a15 100644
--- a/lib/Checker/RegionStore.cpp
+++ b/lib/Checker/RegionStore.cpp
@@ -41,25 +41,25 @@ public:
enum Kind { Direct = 0x0, Default = 0x1 };
private:
llvm ::PointerIntPair<const MemRegion*, 1> P;
- uint64_t Offset;
-
+ uint64_t Offset;
+
explicit BindingKey(const MemRegion *r, uint64_t offset, Kind k)
: P(r, (unsigned) k), Offset(offset) { assert(r); }
public:
-
+
bool isDefault() const { return P.getInt() == Default; }
bool isDirect() const { return P.getInt() == Direct; }
-
+
const MemRegion *getRegion() const { return P.getPointer(); }
uint64_t getOffset() const { return Offset; }
-
+
void Profile(llvm::FoldingSetNodeID& ID) const {
ID.AddPointer(P.getOpaqueValue());
ID.AddInteger(Offset);
}
-
+
static BindingKey Make(const MemRegion *R, Kind k);
-
+
bool operator<(const BindingKey &X) const {
if (P.getOpaqueValue() < X.P.getOpaqueValue())
return true;
@@ -67,16 +67,16 @@ public:
return false;
return Offset < X.Offset;
}
-
+
bool operator==(const BindingKey &X) const {
return P.getOpaqueValue() == X.P.getOpaqueValue() &&
Offset == X.Offset;
}
-};
+};
} // end anonymous namespace
namespace llvm {
- static inline
+ static inline
llvm::raw_ostream& operator<<(llvm::raw_ostream& os, BindingKey K) {
os << '(' << K.getRegion() << ',' << K.getOffset()
<< ',' << (K.isDirect() ? "direct" : "default")
@@ -174,7 +174,7 @@ public:
void process(llvm::SmallVectorImpl<const SubRegion*> &WL, const SubRegion *R);
~RegionStoreSubRegionMap() {}
-
+
const Set *getSubRegions(const MemRegion *Parent) const {
Map::const_iterator I = M.find(Parent);
return I == M.end() ? NULL : &I->second;
@@ -196,13 +196,10 @@ public:
}
};
-
+
class RegionStoreManager : public StoreManager {
const RegionStoreFeatures Features;
RegionBindings::Factory RBFactory;
-
- typedef llvm::DenseMap<Store, RegionStoreSubRegionMap*> SMCache;
- SMCache SC;
public:
RegionStoreManager(GRStateManager& mgr, const RegionStoreFeatures &f)
@@ -210,11 +207,6 @@ public:
Features(f),
RBFactory(mgr.getAllocator()) {}
- virtual ~RegionStoreManager() {
- for (SMCache::iterator I = SC.begin(), E = SC.end(); I != E; ++I)
- delete (*I).second;
- }
-
SubRegionMap *getSubRegionMap(Store store) {
return getRegionStoreSubRegionMap(store);
}
@@ -226,10 +218,10 @@ public:
/// getDefaultBinding - Returns an SVal* representing an optional default
/// binding associated with a region and its subregions.
Optional<SVal> getDefaultBinding(RegionBindings B, const MemRegion *R);
-
+
/// setImplicitDefaultValue - Set the default binding for the provided
/// MemRegion to the value implicitly defined for compound literals when
- /// the value is not specified.
+ /// the value is not specified.
Store setImplicitDefaultValue(Store store, const MemRegion *R, QualType T);
/// ArrayToPointer - Emulates the "decay" of an array to a pointer
@@ -250,11 +242,11 @@ public:
// Binding values to regions.
//===-------------------------------------------------------------------===//
- Store InvalidateRegion(Store store, const MemRegion *R, const Expr *E,
+ Store InvalidateRegion(Store store, const MemRegion *R, const Expr *E,
unsigned Count, InvalidatedSymbols *IS) {
return RegionStoreManager::InvalidateRegions(store, &R, &R+1, E, Count, IS);
}
-
+
Store InvalidateRegions(Store store,
const MemRegion * const *Begin,
const MemRegion * const *End,
@@ -262,7 +254,7 @@ public:
InvalidatedSymbols *IS);
public: // Made public for helper classes.
-
+
void RemoveSubRegionBindings(RegionBindings &B, const MemRegion *R,
RegionStoreSubRegionMap &M);
@@ -270,17 +262,17 @@ public: // Made public for helper classes.
RegionBindings Add(RegionBindings B, const MemRegion *R,
BindingKey::Kind k, SVal V);
-
+
const SVal *Lookup(RegionBindings B, BindingKey K);
const SVal *Lookup(RegionBindings B, const MemRegion *R, BindingKey::Kind k);
RegionBindings Remove(RegionBindings B, BindingKey K);
RegionBindings Remove(RegionBindings B, const MemRegion *R,
BindingKey::Kind k);
-
+
RegionBindings Remove(RegionBindings B, const MemRegion *R) {
return Remove(Remove(B, R, BindingKey::Direct), R, BindingKey::Default);
- }
+ }
Store Remove(Store store, BindingKey K);
@@ -306,7 +298,7 @@ public: // Part of public interface to class.
Store KillStruct(Store store, const TypedRegion* R);
Store Remove(Store store, Loc LV);
-
+
//===------------------------------------------------------------------===//
// Loading values from regions.
@@ -373,7 +365,7 @@ public: // Part of public interface to class.
//===------------------------------------------------------------------===//
const GRState *setExtent(const GRState *state,const MemRegion* R,SVal Extent);
- DefinedOrUnknownSVal getSizeInElements(const GRState *state,
+ DefinedOrUnknownSVal getSizeInElements(const GRState *state,
const MemRegion* R, QualType EleTy);
//===------------------------------------------------------------------===//
@@ -449,85 +441,148 @@ RegionStoreManager::getRegionStoreSubRegionMap(Store store) {
}
//===----------------------------------------------------------------------===//
-// Binding invalidation.
+// Region Cluster analysis.
//===----------------------------------------------------------------------===//
-void RegionStoreManager::RemoveSubRegionBindings(RegionBindings &B,
- const MemRegion *R,
- RegionStoreSubRegionMap &M) {
-
- if (const RegionStoreSubRegionMap::Set *S = M.getSubRegions(R))
- for (RegionStoreSubRegionMap::Set::iterator I = S->begin(), E = S->end();
- I != E; ++I)
- RemoveSubRegionBindings(B, *I, M);
-
- B = Remove(B, R);
-}
-
namespace {
-class InvalidateRegionsWorker {
+template <typename DERIVED>
+class ClusterAnalysis {
+protected:
typedef BumpVector<BindingKey> RegionCluster;
typedef llvm::DenseMap<const MemRegion *, RegionCluster *> ClusterMap;
- typedef llvm::SmallVector<std::pair<const MemRegion *,RegionCluster*>, 10>
- WorkList;
+ llvm::DenseMap<const RegionCluster*, unsigned> Visited;
+ typedef llvm::SmallVector<std::pair<const MemRegion *, RegionCluster*>, 10>
+ WorkList;
BumpVectorContext BVC;
ClusterMap ClusterM;
WorkList WL;
-
+
RegionStoreManager &RM;
- StoreManager::InvalidatedSymbols *IS;
ASTContext &Ctx;
ValueManager &ValMgr;
-
+
+ RegionBindings B;
+
public:
- InvalidateRegionsWorker(RegionStoreManager &rm,
- StoreManager::InvalidatedSymbols *is,
- ASTContext &ctx, ValueManager &valMgr)
- : RM(rm), IS(is), Ctx(ctx), ValMgr(valMgr) {}
-
- Store InvalidateRegions(Store store, const MemRegion * const *I,
- const MemRegion * const *E,
- const Expr *Ex, unsigned Count);
-
-private:
- void AddToWorkList(BindingKey K);
- void AddToWorkList(const MemRegion *R);
- void AddToCluster(BindingKey K);
- RegionCluster **getCluster(const MemRegion *R);
- void VisitBinding(SVal V);
-};
-}
+ ClusterAnalysis(RegionStoreManager &rm, GRStateManager &StateMgr,
+ RegionBindings b)
+ : RM(rm), Ctx(StateMgr.getContext()), ValMgr(StateMgr.getValueManager()),
+ B(b) {}
+
+ RegionBindings getRegionBindings() const { return B; }
+
+ void AddToCluster(BindingKey K) {
+ const MemRegion *R = K.getRegion();
+ const MemRegion *baseR = R->getBaseRegion();
+ RegionCluster &C = getCluster(baseR);
+ C.push_back(K, BVC);
+ static_cast<DERIVED*>(this)->VisitAddedToCluster(baseR, C);
+ }
-void InvalidateRegionsWorker::AddToCluster(BindingKey K) {
- const MemRegion *R = K.getRegion();
- const MemRegion *baseR = R->getBaseRegion();
- RegionCluster **CPtr = getCluster(baseR);
- assert(*CPtr);
- (*CPtr)->push_back(K, BVC);
-}
+ bool isVisited(const MemRegion *R) {
+ return (bool) Visited[&getCluster(R->getBaseRegion())];
+ }
-void InvalidateRegionsWorker::AddToWorkList(BindingKey K) {
- AddToWorkList(K.getRegion());
-}
+ RegionCluster& getCluster(const MemRegion *R) {
+ RegionCluster *&CRef = ClusterM[R];
+ if (!CRef) {
+ void *Mem = BVC.getAllocator().template Allocate<RegionCluster>();
+ CRef = new (Mem) RegionCluster(BVC, 10);
+ }
+ return *CRef;
+ }
-void InvalidateRegionsWorker::AddToWorkList(const MemRegion *R) {
- const MemRegion *baseR = R->getBaseRegion();
- RegionCluster **CPtr = getCluster(baseR);
- if (RegionCluster *C = *CPtr) {
- WL.push_back(std::make_pair(baseR, C));
- *CPtr = NULL;
+ void GenerateClusters() {
+ // Scan the entire set of bindings and make the region clusters.
+ for (RegionBindings::iterator RI = B.begin(), RE = B.end(); RI != RE; ++RI){
+ AddToCluster(RI.getKey());
+ if (const MemRegion *R = RI.getData().getAsRegion()) {
+ // Generate a cluster, but don't add the region to the cluster
+ // if there aren't any bindings.
+ getCluster(R->getBaseRegion());
+ }
+ }
+ }
+
+ bool AddToWorkList(const MemRegion *R, RegionCluster &C) {
+ if (unsigned &visited = Visited[&C])
+ return false;
+ else
+ visited = 1;
+
+ WL.push_back(std::make_pair(R, &C));
+ return true;
+ }
+
+ bool AddToWorkList(BindingKey K) {
+ return AddToWorkList(K.getRegion());
}
-}
-InvalidateRegionsWorker::RegionCluster **
-InvalidateRegionsWorker::getCluster(const MemRegion *R) {
- RegionCluster *&CRef = ClusterM[R];
- if (!CRef) {
- void *Mem = BVC.getAllocator().Allocate<RegionCluster>();
- CRef = new (Mem) RegionCluster(BVC, 10);
+ bool AddToWorkList(const MemRegion *R) {
+ const MemRegion *baseR = R->getBaseRegion();
+ return AddToWorkList(baseR, getCluster(baseR));
+ }
+
+ void RunWorkList() {
+ while (!WL.empty()) {
+ const MemRegion *baseR;
+ RegionCluster *C;
+ llvm::tie(baseR, C) = WL.back();
+ WL.pop_back();
+
+ // First visit the cluster.
+ static_cast<DERIVED*>(this)->VisitCluster(baseR, C->begin(), C->end());
+
+ // Next, visit the region.
+ static_cast<DERIVED*>(this)->VisitRegion(baseR);
+ }
}
- return &CRef;
+
+public:
+ void VisitAddedToCluster(const MemRegion *baseR, RegionCluster &C) {}
+ void VisitCluster(const MemRegion *baseR, BindingKey *I, BindingKey *E) {}
+ void VisitRegion(const MemRegion *baseR) {}
+};
+}
+
+//===----------------------------------------------------------------------===//
+// Binding invalidation.
+//===----------------------------------------------------------------------===//
+
+void RegionStoreManager::RemoveSubRegionBindings(RegionBindings &B,
+ const MemRegion *R,
+ RegionStoreSubRegionMap &M) {
+
+ if (const RegionStoreSubRegionMap::Set *S = M.getSubRegions(R))
+ for (RegionStoreSubRegionMap::Set::iterator I = S->begin(), E = S->end();
+ I != E; ++I)
+ RemoveSubRegionBindings(B, *I, M);
+
+ B = Remove(B, R);
+}
+
+namespace {
+class InvalidateRegionsWorker : public ClusterAnalysis<InvalidateRegionsWorker>
+{
+ const Expr *Ex;
+ unsigned Count;
+ StoreManager::InvalidatedSymbols *IS;
+public:
+ InvalidateRegionsWorker(RegionStoreManager &rm,
+ GRStateManager &stateMgr,
+ RegionBindings b,
+ const Expr *ex, unsigned count,
+ StoreManager::InvalidatedSymbols *is)
+ : ClusterAnalysis<InvalidateRegionsWorker>(rm, stateMgr, b),
+ Ex(ex), Count(count), IS(is) {}
+
+ void VisitCluster(const MemRegion *baseR, BindingKey *I, BindingKey *E);
+ void VisitRegion(const MemRegion *baseR);
+
+private:
+ void VisitBinding(SVal V);
+};
}
void InvalidateRegionsWorker::VisitBinding(SVal V) {
@@ -535,7 +590,7 @@ void InvalidateRegionsWorker::VisitBinding(SVal V) {
if (IS)
if (SymbolRef Sym = V.getAsSymbol())
IS->insert(Sym);
-
+
if (const MemRegion *R = V.getAsRegion()) {
AddToWorkList(R);
return;
@@ -558,112 +613,82 @@ void InvalidateRegionsWorker::VisitBinding(SVal V) {
}
}
-Store InvalidateRegionsWorker::InvalidateRegions(Store store,
- const MemRegion * const *I,
- const MemRegion * const *E,
- const Expr *Ex, unsigned Count)
-{
- RegionBindings B = RegionStoreManager::GetRegionBindings(store);
-
- // Scan the entire store and make the region clusters.
- for (RegionBindings::iterator RI = B.begin(), RE = B.end(); RI != RE; ++RI) {
- AddToCluster(RI.getKey());
- if (const MemRegion *R = RI.getData().getAsRegion()) {
- // Generate a cluster, but don't add the region to the cluster
- // if there aren't any bindings.
- getCluster(R->getBaseRegion());
- }
+void InvalidateRegionsWorker::VisitCluster(const MemRegion *baseR,
+ BindingKey *I, BindingKey *E) {
+ for ( ; I != E; ++I) {
+ // Get the old binding. Is it a region? If so, add it to the worklist.
+ const BindingKey &K = *I;
+ if (const SVal *V = RM.Lookup(B, K))
+ VisitBinding(*V);
+
+ B = RM.Remove(B, K);
}
-
- // Add the cluster for I .. E to a worklist.
- for ( ; I != E; ++I)
- AddToWorkList(*I);
+}
- while (!WL.empty()) {
- const MemRegion *baseR;
- RegionCluster *C;
- llvm::tie(baseR, C) = WL.back();
- WL.pop_back();
-
- for (RegionCluster::iterator I = C->begin(), E = C->end(); I != E; ++I) {
- BindingKey K = *I;
-
- // Get the old binding. Is it a region? If so, add it to the worklist.
- if (const SVal *V = RM.Lookup(B, K))
- VisitBinding(*V);
-
- B = RM.Remove(B, K);
- }
-
- // Now inspect the base region.
+void InvalidateRegionsWorker::VisitRegion(const MemRegion *baseR) {
+ if (IS) {
+ // Symbolic region? Mark that symbol touched by the invalidation.
+ if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR))
+ IS->insert(SR->getSymbol());
+ }
- if (IS) {
- // Symbolic region? Mark that symbol touched by the invalidation.
- if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR))
- IS->insert(SR->getSymbol());
+ // BlockDataRegion? If so, invalidate captured variables that are passed
+ // by reference.
+ if (const BlockDataRegion *BR = dyn_cast<BlockDataRegion>(baseR)) {
+ for (BlockDataRegion::referenced_vars_iterator
+ BI = BR->referenced_vars_begin(), BE = BR->referenced_vars_end() ;
+ BI != BE; ++BI) {
+ const VarRegion *VR = *BI;
+ const VarDecl *VD = VR->getDecl();
+ if (VD->getAttr<BlocksAttr>() || !VD->hasLocalStorage())
+ AddToWorkList(VR);
}
-
- // BlockDataRegion? If so, invalidate captured variables that are passed
- // by reference.
- if (const BlockDataRegion *BR = dyn_cast<BlockDataRegion>(baseR)) {
- for (BlockDataRegion::referenced_vars_iterator
- BI = BR->referenced_vars_begin(), BE = BR->referenced_vars_end() ;
- BI != BE; ++BI) {
- const VarRegion *VR = *BI;
- const VarDecl *VD = VR->getDecl();
- if (VD->getAttr<BlocksAttr>() || !VD->hasLocalStorage())
- AddToWorkList(VR);
- }
- continue;
- }
-
- if (isa<AllocaRegion>(baseR) || isa<SymbolicRegion>(baseR)) {
- // Invalidate the region by setting its default value to
- // conjured symbol. The type of the symbol is irrelavant.
- DefinedOrUnknownSVal V = ValMgr.getConjuredSymbolVal(baseR, Ex, Ctx.IntTy,
- Count);
- B = RM.Add(B, baseR, BindingKey::Default, V);
- continue;
- }
-
- if (!baseR->isBoundable())
- continue;
-
- const TypedRegion *TR = cast<TypedRegion>(baseR);
- QualType T = TR->getValueType(Ctx);
-
- // Invalidate the binding.
- if (const RecordType *RT = T->getAsStructureType()) {
- const RecordDecl *RD = RT->getDecl()->getDefinition();
+ return;
+ }
+
+ if (isa<AllocaRegion>(baseR) || isa<SymbolicRegion>(baseR)) {
+ // Invalidate the region by setting its default value to
+ // conjured symbol. The type of the symbol is irrelavant.
+ DefinedOrUnknownSVal V = ValMgr.getConjuredSymbolVal(baseR, Ex, Ctx.IntTy,
+ Count);
+ B = RM.Add(B, baseR, BindingKey::Default, V);
+ return;
+ }
+
+ if (!baseR->isBoundable())
+ return;
+
+ const TypedRegion *TR = cast<TypedRegion>(baseR);
+ QualType T = TR->getValueType(Ctx);
+
+ // Invalidate the binding.
+ if (const RecordType *RT = T->getAsStructureType()) {
+ const RecordDecl *RD = RT->getDecl()->getDefinition();
// No record definition. There is nothing we can do.
- if (!RD) {
- B = RM.Remove(B, baseR);
- continue;
- }
-
+ if (!RD) {
+ B = RM.Remove(B, baseR);
+ return;
+ }
+
// Invalidate the region by setting its default value to
// conjured symbol. The type of the symbol is irrelavant.
- DefinedOrUnknownSVal V = ValMgr.getConjuredSymbolVal(baseR, Ex, Ctx.IntTy,
- Count);
- B = RM.Add(B, baseR, BindingKey::Default, V);
- continue;
- }
+ DefinedOrUnknownSVal V = ValMgr.getConjuredSymbolVal(baseR, Ex, Ctx.IntTy,
+ Count);
+ B = RM.Add(B, baseR, BindingKey::Default, V);
+ return;
+ }
- if (const ArrayType *AT = Ctx.getAsArrayType(T)) {
+ if (const ArrayType *AT = Ctx.getAsArrayType(T)) {
// Set the default value of the array to conjured symbol.
- DefinedOrUnknownSVal V =
- ValMgr.getConjuredSymbolVal(baseR, Ex, AT->getElementType(), Count);
- B = RM.Add(B, baseR, BindingKey::Default, V);
- continue;
- }
-
- DefinedOrUnknownSVal V = ValMgr.getConjuredSymbolVal(baseR, Ex, T, Count);
- assert(SymbolManager::canSymbolicate(T) || V.isUnknown());
- B = RM.Add(B, baseR, BindingKey::Direct, V);
+ DefinedOrUnknownSVal V =
+ ValMgr.getConjuredSymbolVal(baseR, Ex, AT->getElementType(), Count);
+ B = RM.Add(B, baseR, BindingKey::Default, V);
+ return;
}
- // Create a new state with the updated bindings.
- return B.getRoot();
+ DefinedOrUnknownSVal V = ValMgr.getConjuredSymbolVal(baseR, Ex, T, Count);
+ assert(SymbolManager::canSymbolicate(T) || V.isUnknown());
+ B = RM.Add(B, baseR, BindingKey::Direct, V);
}
Store RegionStoreManager::InvalidateRegions(Store store,
@@ -671,11 +696,23 @@ Store RegionStoreManager::InvalidateRegions(Store store,
const MemRegion * const *E,
const Expr *Ex, unsigned Count,
InvalidatedSymbols *IS) {
- InvalidateRegionsWorker W(*this, IS, getContext(),
- StateMgr.getValueManager());
- return W.InvalidateRegions(store, I, E, Ex, Count);
+ InvalidateRegionsWorker W(*this, StateMgr,
+ RegionStoreManager::GetRegionBindings(store),
+ Ex, Count, IS);
+
+ // Scan the bindings and generate the clusters.
+ W.GenerateClusters();
+
+ // Add I .. E to the worklist.
+ for ( ; I != E; ++I)
+ W.AddToWorkList(*I);
+
+ W.RunWorkList();
+
+ // Return the new bindings.
+ return W.getRegionBindings().getRoot();
}
-
+
//===----------------------------------------------------------------------===//
// Extents for regions.
//===----------------------------------------------------------------------===//
@@ -686,7 +723,7 @@ DefinedOrUnknownSVal RegionStoreManager::getSizeInElements(const GRState *state,
switch (R->getKind()) {
case MemRegion::CXXThisRegionKind:
- assert(0 && "Cannot get size of 'this' region");
+ assert(0 && "Cannot get size of 'this' region");
case MemRegion::GenericMemSpaceRegionKind:
case MemRegion::StackLocalsSpaceRegionKind:
case MemRegion::StackArgumentsSpaceRegionKind:
@@ -719,7 +756,7 @@ DefinedOrUnknownSVal RegionStoreManager::getSizeInElements(const GRState *state,
if (!CI)
return UnknownVal();
- CharUnits RegionSize =
+ CharUnits RegionSize =
CharUnits::fromQuantity(CI->getValue().getSExtValue());
CharUnits EleSize = getContext().getTypeSizeInChars(EleTy);
assert(RegionSize % EleSize == 0);
@@ -840,7 +877,7 @@ SVal RegionStoreManager::EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R,
// Not yet handled.
case MemRegion::VarRegionKind:
case MemRegion::StringRegionKind: {
-
+
}
// Fall-through.
case MemRegion::CompoundLiteralRegionKind:
@@ -884,13 +921,13 @@ SVal RegionStoreManager::EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R,
MRMgr.getElementRegion(ER->getElementType(), NewIdx,
ER->getSuperRegion(), getContext());
return ValMgr.makeLoc(NewER);
- }
+ }
if (0 == Base->getValue()) {
const MemRegion* NewER =
MRMgr.getElementRegion(ER->getElementType(), R,
ER->getSuperRegion(), getContext());
- return ValMgr.makeLoc(NewER);
- }
+ return ValMgr.makeLoc(NewER);
+ }
}
return UnknownVal();
@@ -900,10 +937,10 @@ SVal RegionStoreManager::EvalBinOp(BinaryOperator::Opcode Op, Loc L, NonLoc R,
// Loading values from regions.
//===----------------------------------------------------------------------===//
-Optional<SVal> RegionStoreManager::getDirectBinding(RegionBindings B,
+Optional<SVal> RegionStoreManager::getDirectBinding(RegionBindings B,
const MemRegion *R) {
if (const SVal *V = Lookup(B, R, BindingKey::Direct))
- return *V;
+ return *V;
return Optional<SVal>();
}
@@ -923,10 +960,10 @@ Optional<SVal> RegionStoreManager::getDefaultBinding(RegionBindings B,
Optional<SVal> RegionStoreManager::getBinding(RegionBindings B,
const MemRegion *R) {
-
+
if (Optional<SVal> V = getDirectBinding(B, R))
return V;
-
+
return getDefaultBinding(B, R);
}
@@ -964,12 +1001,12 @@ RegionStoreManager::GetElementZeroRegion(const MemRegion *R, QualType T) {
SVal RegionStoreManager::Retrieve(Store store, Loc L, QualType T) {
assert(!isa<UnknownVal>(L) && "location unknown");
assert(!isa<UndefinedVal>(L) && "location undefined");
-
+
// FIXME: Is this even possible? Shouldn't this be treated as a null
// dereference at a higher level?
if (isa<loc::ConcreteInt>(L))
return UndefinedVal();
-
+
const MemRegion *MR = cast<loc::MemRegionVal>(L).getRegion();
if (isa<AllocaRegion>(MR) || isa<SymbolicRegion>(MR))
@@ -1029,7 +1066,7 @@ SVal RegionStoreManager::Retrieve(Store store, Loc L, QualType T) {
// bound regions (e.g., several bound bytes), or could be a subset of
// a larger value.
return CastRetrievedVal(RetrieveElement(store, ER), ER, T, false);
- }
+ }
if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R)) {
// FIXME: Here we actually perform an implicit conversion from the loaded
@@ -1047,7 +1084,7 @@ SVal RegionStoreManager::Retrieve(Store store, Loc L, QualType T) {
// that blow past the extent of the variable. If the address of the
// variable is reinterpretted, it is possible we stored a different value
// that could fit within the variable. Either we need to cast these when
- // storing them or reinterpret them lazily (as we do here).
+ // storing them or reinterpret them lazily (as we do here).
return CastRetrievedVal(RetrieveVar(store, VR), VR, T, false);
}
@@ -1096,7 +1133,7 @@ RegionStoreManager::GetLazyBinding(RegionBindings B, const MemRegion *R) {
return std::make_pair(X.first,
MRMgr.getFieldRegionWithSuper(FR, X.second));
}
- // The NULL MemRegion indicates an non-existent lazy binding. A NULL Store is
+ // The NULL MemRegion indicates an non-existent lazy binding. A NULL Store is
// possible for a valid lazy binding.
return std::make_pair((Store) 0, (const MemRegion *) 0);
}
@@ -1112,13 +1149,13 @@ SVal RegionStoreManager::RetrieveElement(Store store,
// Check if the region is an element region of a string literal.
if (const StringRegion *StrR=dyn_cast<StringRegion>(superR)) {
- // FIXME: Handle loads from strings where the literal is treated as
+ // FIXME: Handle loads from strings where the literal is treated as
// an integer, e.g., *((unsigned int*)"hello")
ASTContext &Ctx = getContext();
QualType T = Ctx.getAsArrayType(StrR->getValueType(Ctx))->getElementType();
if (T != Ctx.getCanonicalType(R->getElementType()))
return UnknownVal();
-
+
const StringLiteral *Str = StrR->getStringLiteral();
SVal Idx = R->getIndex();
if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Idx)) {
@@ -1155,7 +1192,7 @@ SVal RegionStoreManager::RetrieveElement(Store store,
// Other cases: give up.
return UnknownVal();
}
-
+
return RetrieveFieldOrElementCommon(store, R, R->getElementType(), superR);
}
@@ -1268,8 +1305,8 @@ SVal RegionStoreManager::RetrieveVar(Store store, const VarRegion *R) {
const VarDecl *VD = R->getDecl();
QualType T = VD->getType();
const MemSpaceRegion *MS = R->getMemorySpace();
-
- if (isa<UnknownSpaceRegion>(MS) ||
+
+ if (isa<UnknownSpaceRegion>(MS) ||
isa<StackArgumentsSpaceRegion>(MS))
return ValMgr.getRegionValueSymbolVal(R);
@@ -1282,9 +1319,9 @@ SVal RegionStoreManager::RetrieveVar(Store store, const VarRegion *R) {
if (T->isPointerType())
return ValMgr.makeNull();
- return UnknownVal();
+ return UnknownVal();
}
-
+
return UndefinedVal();
}
@@ -1402,7 +1439,7 @@ Store RegionStoreManager::Bind(Store store, Loc L, SVal V) {
// Binding directly to a symbolic region should be treated as binding
// to element 0.
QualType T = SR->getSymbol()->getType(getContext());
-
+
// FIXME: Is this the right way to handle symbols that are references?
if (const PointerType *PT = T->getAs<PointerType>())
T = PT->getPointeeType();
@@ -1417,7 +1454,7 @@ Store RegionStoreManager::Bind(Store store, Loc L, SVal V) {
return Add(B, R, BindingKey::Direct, V).getRoot();
}
-Store RegionStoreManager::BindDecl(Store store, const VarRegion *VR,
+Store RegionStoreManager::BindDecl(Store store, const VarRegion *VR,
SVal InitVal) {
QualType T = VR->getDecl()->getType();
@@ -1460,19 +1497,19 @@ Store RegionStoreManager::setImplicitDefaultValue(Store store,
return Add(B, R, BindingKey::Default, V).getRoot();
}
-
-Store RegionStoreManager::BindArray(Store store, const TypedRegion* R,
+
+Store RegionStoreManager::BindArray(Store store, const TypedRegion* R,
SVal Init) {
-
+
ASTContext &Ctx = getContext();
const ArrayType *AT =
cast<ArrayType>(Ctx.getCanonicalType(R->getValueType(Ctx)));
- QualType ElementTy = AT->getElementType();
+ QualType ElementTy = AT->getElementType();
Optional<uint64_t> Size;
-
+
if (const ConstantArrayType* CAT = dyn_cast<ConstantArrayType>(AT))
Size = CAT->getSize().getZExtValue();
-
+
// Check if the init expr is a StringLiteral.
if (isa<loc::MemRegionVal>(Init)) {
const MemRegion* InitR = cast<loc::MemRegionVal>(Init).getRegion();
@@ -1484,11 +1521,11 @@ Store RegionStoreManager::BindArray(Store store, const TypedRegion* R,
// Copy bytes from the string literal into the target array. Trailing bytes
// in the array that are not covered by the string literal are initialized
// to zero.
-
+
// We assume that string constants are bound to
// constant arrays.
uint64_t size = Size.getValue();
-
+
for (uint64_t i = 0; i < size; ++i, ++j) {
if (j >= len)
break;
@@ -1509,10 +1546,10 @@ Store RegionStoreManager::BindArray(Store store, const TypedRegion* R,
return CopyLazyBindings(*LCV, store, R);
// Remaining case: explicit compound values.
-
+
if (Init.isUnknown())
- return setImplicitDefaultValue(store, R, ElementTy);
-
+ return setImplicitDefaultValue(store, R, ElementTy);
+
nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(Init);
nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
uint64_t i = 0;
@@ -1628,14 +1665,14 @@ Store RegionStoreManager::CopyLazyBindings(nonloc::LazyCompoundVal V,
BindingKey BindingKey::Make(const MemRegion *R, Kind k) {
if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
const RegionRawOffset &O = ER->getAsRawOffset();
-
+
if (O.getRegion())
return BindingKey(O.getRegion(), O.getByteOffset(), k);
-
+
// FIXME: There are some ElementRegions for which we cannot compute
// raw offsets yet, including regions with symbolic offsets.
}
-
+
return BindingKey(R, 0, k);
}
@@ -1675,194 +1712,163 @@ Store RegionStoreManager::Remove(Store store, BindingKey K) {
//===----------------------------------------------------------------------===//
// State pruning.
//===----------------------------------------------------------------------===//
-
-Store RegionStoreManager::RemoveDeadBindings(Store store, Stmt* Loc,
- SymbolReaper& SymReaper,
- llvm::SmallVectorImpl<const MemRegion*>& RegionRoots)
-{
- typedef std::pair<Store, const MemRegion *> RBDNode;
- RegionBindings B = GetRegionBindings(store);
+namespace {
+class RemoveDeadBindingsWorker :
+ public ClusterAnalysis<RemoveDeadBindingsWorker> {
+ llvm::SmallVector<const SymbolicRegion*, 12> Postponed;
+ SymbolReaper &SymReaper;
+ Stmt *Loc;
+public:
+ RemoveDeadBindingsWorker(RegionStoreManager &rm, GRStateManager &stateMgr,
+ RegionBindings b, SymbolReaper &symReaper,
+ Stmt *loc)
+ : ClusterAnalysis<RemoveDeadBindingsWorker>(rm, stateMgr, b),
+ SymReaper(symReaper), Loc(loc) {}
+
+ // Called by ClusterAnalysis.
+ void VisitAddedToCluster(const MemRegion *baseR, RegionCluster &C);
+ void VisitCluster(const MemRegion *baseR, BindingKey *I, BindingKey *E);
+ void VisitRegion(const MemRegion *baseR);
+
+ bool UpdatePostponed();
+ void VisitBinding(SVal V);
+};
+}
- // The backmap from regions to subregions.
- llvm::OwningPtr<RegionStoreSubRegionMap>
- SubRegions(getRegionStoreSubRegionMap(store));
-
- // Do a pass over the regions in the store. For VarRegions we check if
- // the variable is still live and if so add it to the list of live roots.
- // For other regions we populate our region backmap.
- llvm::SmallVector<const MemRegion*, 10> IntermediateRoots;
-
- // Scan the direct bindings for "intermediate" roots.
- for (RegionBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) {
- const MemRegion *R = I.getKey().getRegion();
- IntermediateRoots.push_back(R);
- }
-
- // Process the "intermediate" roots to find if they are referenced by
- // real roots.
- llvm::SmallVector<RBDNode, 10> WorkList;
- llvm::SmallVector<RBDNode, 10> Postponed;
-
- llvm::DenseSet<const MemRegion*> IntermediateVisited;
-
- while (!IntermediateRoots.empty()) {
- const MemRegion* R = IntermediateRoots.back();
- IntermediateRoots.pop_back();
-
- if (IntermediateVisited.count(R))
- continue;
- IntermediateVisited.insert(R);
-
- if (const VarRegion* VR = dyn_cast<VarRegion>(R)) {
- if (SymReaper.isLive(Loc, VR))
- WorkList.push_back(std::make_pair(store, VR));
- continue;
- }
-
- if (const SymbolicRegion* SR = dyn_cast<SymbolicRegion>(R)) {
- llvm::SmallVectorImpl<RBDNode> &Q =
- SymReaper.isLive(SR->getSymbol()) ? WorkList : Postponed;
-
- Q.push_back(std::make_pair(store, SR));
+void RemoveDeadBindingsWorker::VisitAddedToCluster(const MemRegion *baseR,
+ RegionCluster &C) {
- continue;
- }
-
- // Add the super region for R to the worklist if it is a subregion.
- if (const SubRegion* superR =
- dyn_cast<SubRegion>(cast<SubRegion>(R)->getSuperRegion()))
- IntermediateRoots.push_back(superR);
+ if (const VarRegion *VR = dyn_cast<VarRegion>(baseR)) {
+ if (SymReaper.isLive(Loc, VR))
+ AddToWorkList(baseR, C);
+
+ return;
}
- // Enqueue the RegionRoots onto WorkList.
- for (llvm::SmallVectorImpl<const MemRegion*>::iterator I=RegionRoots.begin(),
- E=RegionRoots.end(); I!=E; ++I) {
- WorkList.push_back(std::make_pair(store, *I));
- }
- RegionRoots.clear();
-
- llvm::DenseSet<RBDNode> Visited;
-
-tryAgain:
- while (!WorkList.empty()) {
- RBDNode N = WorkList.back();
- WorkList.pop_back();
-
- // Have we visited this node before?
- if (Visited.count(N))
- continue;
- Visited.insert(N);
-
- const MemRegion *R = N.second;
- Store store_N = N.first;
-
- // Enqueue subregions.
- RegionStoreSubRegionMap *M;
-
- if (store == store_N)
- M = SubRegions.get();
- else {
- RegionStoreSubRegionMap *& SM = SC[store_N];
- if (!SM)
- SM = getRegionStoreSubRegionMap(store_N);
- M = SM;
- }
+ if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR)) {
+ if (SymReaper.isLive(SR->getSymbol()))
+ AddToWorkList(SR, C);
+ else
+ Postponed.push_back(SR);
- if (const RegionStoreSubRegionMap::Set *S = M->getSubRegions(R))
- for (RegionStoreSubRegionMap::Set::iterator I = S->begin(), E = S->end();
- I != E; ++I)
- WorkList.push_back(std::make_pair(store_N, *I));
-
- // Enqueue the super region.
- if (const SubRegion *SR = dyn_cast<SubRegion>(R)) {
- const MemRegion *superR = SR->getSuperRegion();
- if (!isa<MemSpaceRegion>(superR)) {
- // If 'R' is a field or an element, we want to keep the bindings
- // for the other fields and elements around. The reason is that
- // pointer arithmetic can get us to the other fields or elements.
- assert(isa<FieldRegion>(R) || isa<ElementRegion>(R)
- || isa<ObjCIvarRegion>(R));
- WorkList.push_back(std::make_pair(store_N, superR));
- }
- }
+ return;
+ }
+}
- // Mark the symbol for any live SymbolicRegion as "live". This means we
- // should continue to track that symbol.
- if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(R))
- SymReaper.markLive(SymR->getSymbol());
-
- // For BlockDataRegions, enqueue the VarRegions for variables marked
- // with __block (passed-by-reference).
- // via BlockDeclRefExprs.
- if (const BlockDataRegion *BD = dyn_cast<BlockDataRegion>(R)) {
- for (BlockDataRegion::referenced_vars_iterator
- RI = BD->referenced_vars_begin(), RE = BD->referenced_vars_end();
- RI != RE; ++RI) {
- if ((*RI)->getDecl()->getAttr<BlocksAttr>())
- WorkList.push_back(std::make_pair(store_N, *RI));
- }
- // No possible data bindings on a BlockDataRegion. Continue to the
- // next region in the worklist.
- continue;
+void RemoveDeadBindingsWorker::VisitCluster(const MemRegion *baseR,
+ BindingKey *I, BindingKey *E) {
+ for ( ; I != E; ++I) {
+ const MemRegion *R = I->getRegion();
+ if (R != baseR)
+ VisitRegion(R);
+ }
+}
+
+void RemoveDeadBindingsWorker::VisitBinding(SVal V) {
+ // Is it a LazyCompoundVal? All referenced regions are live as well.
+ if (const nonloc::LazyCompoundVal *LCS =
+ dyn_cast<nonloc::LazyCompoundVal>(&V)) {
+
+ const MemRegion *LazyR = LCS->getRegion();
+ RegionBindings B = RegionStoreManager::GetRegionBindings(LCS->getStore());
+ for (RegionBindings::iterator RI = B.begin(), RE = B.end(); RI != RE; ++RI){
+ const MemRegion *baseR = RI.getKey().getRegion();
+ if (cast<SubRegion>(baseR)->isSubRegionOf(LazyR))
+ VisitBinding(RI.getData());
}
+ return;
+ }
- RegionBindings B_N = GetRegionBindings(store_N);
-
- // Get the data binding for R (if any).
- Optional<SVal> V = getBinding(B_N, R);
-
- if (V) {
- // Check for lazy bindings.
- if (const nonloc::LazyCompoundVal *LCV =
- dyn_cast<nonloc::LazyCompoundVal>(V.getPointer())) {
-
- const LazyCompoundValData *D = LCV->getCVData();
- WorkList.push_back(std::make_pair(D->getStore(), D->getRegion()));
- }
- else {
- // Update the set of live symbols.
- for (SVal::symbol_iterator SI=V->symbol_begin(), SE=V->symbol_end();
- SI!=SE;++SI)
- SymReaper.markLive(*SI);
-
- // If V is a region, then add it to the worklist.
- if (const MemRegion *RX = V->getAsRegion())
- WorkList.push_back(std::make_pair(store_N, RX));
- }
+ // If V is a region, then add it to the worklist.
+ if (const MemRegion *R = V.getAsRegion())
+ AddToWorkList(R);
+
+ // Update the set of live symbols.
+ for (SVal::symbol_iterator SI=V.symbol_begin(), SE=V.symbol_end();
+ SI!=SE;++SI)
+ SymReaper.markLive(*SI);
+}
+
+void RemoveDeadBindingsWorker::VisitRegion(const MemRegion *R) {
+ // Mark this region "live" by adding it to the worklist. This will cause
+ // use to visit all regions in the cluster (if we haven't visited them
+ // already).
+ AddToWorkList(R);
+
+ // Mark the symbol for any live SymbolicRegion as "live". This means we
+ // should continue to track that symbol.
+ if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(R))
+ SymReaper.markLive(SymR->getSymbol());
+
+ // For BlockDataRegions, enqueue the VarRegions for variables marked
+ // with __block (passed-by-reference).
+ // via BlockDeclRefExprs.
+ if (const BlockDataRegion *BD = dyn_cast<BlockDataRegion>(R)) {
+ for (BlockDataRegion::referenced_vars_iterator
+ RI = BD->referenced_vars_begin(), RE = BD->referenced_vars_end();
+ RI != RE; ++RI) {
+ if ((*RI)->getDecl()->getAttr<BlocksAttr>())
+ AddToWorkList(*RI);
}
+
+ // No possible data bindings on a BlockDataRegion.
+ return;
}
-
+
+ // Get the data binding for R (if any).
+ if (Optional<SVal> V = RM.getBinding(B, R))
+ VisitBinding(*V);
+}
+
+bool RemoveDeadBindingsWorker::UpdatePostponed() {
// See if any postponed SymbolicRegions are actually live now, after
// having done a scan.
- for (llvm::SmallVectorImpl<RBDNode>::iterator I = Postponed.begin(),
- E = Postponed.end() ; I != E ; ++I) {
- if (const SymbolicRegion *SR = cast_or_null<SymbolicRegion>(I->second)) {
+ bool changed = false;
+
+ for (llvm::SmallVectorImpl<const SymbolicRegion*>::iterator
+ I = Postponed.begin(), E = Postponed.end() ; I != E ; ++I) {
+ if (const SymbolicRegion *SR = cast_or_null<SymbolicRegion>(*I)) {
if (SymReaper.isLive(SR->getSymbol())) {
- WorkList.push_back(*I);
- I->second = NULL;
+ changed |= AddToWorkList(SR);
+ *I = NULL;
}
}
}
-
- if (!WorkList.empty())
- goto tryAgain;
-
+
+ return changed;
+}
+
+Store RegionStoreManager::RemoveDeadBindings(Store store, Stmt* Loc,
+ SymbolReaper& SymReaper,
+ llvm::SmallVectorImpl<const MemRegion*>& RegionRoots)
+{
+ RegionBindings B = GetRegionBindings(store);
+ RemoveDeadBindingsWorker W(*this, StateMgr, B, SymReaper, Loc);
+ W.GenerateClusters();
+
+ // Enqueue the region roots onto the worklist.
+ for (llvm::SmallVectorImpl<const MemRegion*>::iterator I=RegionRoots.begin(),
+ E=RegionRoots.end(); I!=E; ++I)
+ W.AddToWorkList(*I);
+
+ do W.RunWorkList(); while (W.UpdatePostponed());
+
// We have now scanned the store, marking reachable regions and symbols
// as live. We now remove all the regions that are dead from the store
// as well as update DSymbols with the set symbols that are now dead.
- Store new_store = store;
for (RegionBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) {
- const MemRegion* R = I.getKey().getRegion();
- // If this region live? Is so, none of its symbols are dead.
- if (Visited.count(std::make_pair(store, R)))
+ const BindingKey &K = I.getKey();
+
+ // If the cluster has been visited, we know the region has been marked.
+ if (W.isVisited(K.getRegion()))
continue;
- // Remove this dead region from the store.
- new_store = Remove(new_store, I.getKey());
+ // Remove the dead entry.
+ B = Remove(B, K);
- // Mark all non-live symbols that this region references as dead.
- if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(R))
+ // Mark all non-live symbols that this binding references as dead.
+ if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(K.getRegion()))
SymReaper.maybeDead(SymR->getSymbol());
SVal X = I.getData();
@@ -1871,9 +1877,10 @@ tryAgain:
SymReaper.maybeDead(*SI);
}
- return new_store;
+ return B.getRoot();
}
+
GRState const *RegionStoreManager::EnterStackFrame(GRState const *state,
StackFrameContext const *frame) {
FunctionDecl const *FD = cast<FunctionDecl>(frame->getDecl());
diff --git a/lib/Checker/SVals.cpp b/lib/Checker/SVals.cpp
index 28b3fce..4bfa2cd 100644
--- a/lib/Checker/SVals.cpp
+++ b/lib/Checker/SVals.cpp
@@ -70,6 +70,25 @@ SymbolRef SVal::getAsLocSymbol() const {
return NULL;
}
+/// Get the symbol in the SVal or its base region.
+SymbolRef SVal::getLocSymbolInBase() const {
+ const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this);
+
+ if (!X)
+ return 0;
+
+ const MemRegion *R = X->getRegion();
+
+ while (const SubRegion *SR = dyn_cast<SubRegion>(R)) {
+ if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SR))
+ return SymR->getSymbol();
+ else
+ R = SR->getSuperRegion();
+ }
+
+ return 0;
+}
+
/// getAsSymbol - If this Sval wraps a symbol return that SymbolRef.
/// Otherwise return 0.
// FIXME: should we consider SymbolRef wrapped in CodeTextRegion?
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 0f3502e..c3302e6 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -36,8 +36,9 @@ using namespace clang;
using namespace clang::CodeGen;
CGDebugInfo::CGDebugInfo(CodeGenModule &CGM)
- : CGM(CGM), isMainCompileUnitCreated(false), DebugFactory(CGM.getModule()),
- BlockLiteralGenericSet(false) {
+ : CGM(CGM), DebugFactory(CGM.getModule()),
+ FwdDeclCount(0), BlockLiteralGenericSet(false) {
+ CreateCompileUnit();
}
CGDebugInfo::~CGDebugInfo() {
@@ -85,45 +86,29 @@ llvm::StringRef CGDebugInfo::getFunctionName(const FunctionDecl *FD) {
return llvm::StringRef(StrPtr, NS.length());
}
-/// getOrCreateCompileUnit - Get the compile unit from the cache or create a new
-/// one if necessary. This returns null for invalid source locations.
-llvm::DICompileUnit CGDebugInfo::getOrCreateCompileUnit(SourceLocation Loc) {
- // Get source file information.
- const char *FileName = "<unknown>";
+/// getOrCreateFile - Get the file debug info descriptor for the input location.
+llvm::DIFile CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
+ if (!Loc.isValid())
+ // If Location is not valid then use main input file.
+ return DebugFactory.CreateFile(TheCU.getFilename(), TheCU.getDirectory(),
+ TheCU);
SourceManager &SM = CGM.getContext().getSourceManager();
- if (Loc.isValid()) {
- PresumedLoc PLoc = SM.getPresumedLoc(Loc);
- FileName = PLoc.getFilename();
- unsigned FID = PLoc.getIncludeLoc().getRawEncoding();
-
- // See if this compile unit has been used before for this valid location.
- llvm::DICompileUnit &Unit = CompileUnitCache[FID];
- if (!Unit.isNull()) return Unit;
- }
+ PresumedLoc PLoc = SM.getPresumedLoc(Loc);
+ llvm::sys::Path AbsFileName(PLoc.getFilename());
+ AbsFileName.makeAbsolute();
+
+ return DebugFactory.CreateFile(AbsFileName.getLast(),
+ AbsFileName.getDirname(), TheCU);
+}
+/// CreateCompileUnit - Create new compile unit.
+void CGDebugInfo::CreateCompileUnit() {
// Get absolute path name.
- llvm::sys::Path AbsFileName(FileName);
+ llvm::sys::Path AbsFileName(CGM.getCodeGenOpts().MainFileName);
AbsFileName.makeAbsolute();
- // See if thie compile unit is representing main source file. Each source
- // file has corresponding compile unit. There is only one main source
- // file at a time.
- bool isMain = false;
- const LangOptions &LO = CGM.getLangOptions();
- const CodeGenOptions &CGO = CGM.getCodeGenOpts();
- if (isMainCompileUnitCreated == false) {
- if (!CGO.MainFileName.empty()) {
- if (AbsFileName.getLast() == CGO.MainFileName)
- isMain = true;
- } else {
- if (Loc.isValid() && SM.isFromMainFile(Loc))
- isMain = true;
- }
- if (isMain)
- isMainCompileUnitCreated = true;
- }
-
unsigned LangTag;
+ const LangOptions &LO = CGM.getLangOptions();
if (LO.CPlusPlus) {
if (LO.ObjC1)
LangTag = llvm::dwarf::DW_LANG_ObjC_plus_plus;
@@ -149,22 +134,15 @@ llvm::DICompileUnit CGDebugInfo::getOrCreateCompileUnit(SourceLocation Loc) {
RuntimeVers = LO.ObjCNonFragileABI ? 2 : 1;
// Create new compile unit.
- llvm::DICompileUnit Unit = DebugFactory.CreateCompileUnit(
- LangTag, AbsFileName.getLast(), AbsFileName.getDirname(), Producer, isMain,
+ TheCU = DebugFactory.CreateCompileUnit(
+ LangTag, AbsFileName.getLast(), AbsFileName.getDirname(), Producer, true,
LO.Optimize, CGM.getCodeGenOpts().DwarfDebugFlags, RuntimeVers);
-
- if (Loc.isValid()) {
- PresumedLoc PLoc = SM.getPresumedLoc(Loc);
- unsigned FID = PLoc.getIncludeLoc().getRawEncoding();
- CompileUnitCache[FID] = Unit;
- }
- return Unit;
}
/// CreateType - Get the Basic type from the cache or create a new
/// one if necessary.
llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT,
- llvm::DICompileUnit Unit) {
+ llvm::DIFile Unit) {
unsigned Encoding = 0;
switch (BT->getKind()) {
default:
@@ -201,7 +179,7 @@ llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT,
}
llvm::DIType CGDebugInfo::CreateType(const ComplexType *Ty,
- llvm::DICompileUnit Unit) {
+ llvm::DIFile Unit) {
// Bit size, align and offset of the type.
unsigned Encoding = llvm::dwarf::DW_ATE_complex_float;
if (Ty->isComplexIntegerType())
@@ -220,7 +198,7 @@ llvm::DIType CGDebugInfo::CreateType(const ComplexType *Ty,
/// CreateCVRType - Get the qualified type from the cache or create
/// a new one if necessary.
-llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DICompileUnit Unit) {
+llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DIFile Unit) {
QualifierCollector Qc;
const Type *T = Qc.strip(Ty);
@@ -250,13 +228,13 @@ llvm::DIType CGDebugInfo::CreateQualifiedType(QualType Ty, llvm::DICompileUnit U
// No need to fill in the Name, Line, Size, Alignment, Offset in case of
// CVR derived types.
llvm::DIType DbgTy =
- DebugFactory.CreateDerivedType(Tag, Unit, "", llvm::DICompileUnit(),
+ DebugFactory.CreateDerivedType(Tag, Unit, "", Unit,
0, 0, 0, 0, 0, FromTy);
return DbgTy;
}
llvm::DIType CGDebugInfo::CreateType(const ObjCObjectPointerType *Ty,
- llvm::DICompileUnit Unit) {
+ llvm::DIFile Unit) {
llvm::DIType DbgTy =
CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
Ty->getPointeeType(), Unit);
@@ -264,7 +242,7 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCObjectPointerType *Ty,
}
llvm::DIType CGDebugInfo::CreateType(const PointerType *Ty,
- llvm::DICompileUnit Unit) {
+ llvm::DIFile Unit) {
return CreatePointerLikeType(llvm::dwarf::DW_TAG_pointer_type, Ty,
Ty->getPointeeType(), Unit);
}
@@ -272,7 +250,7 @@ llvm::DIType CGDebugInfo::CreateType(const PointerType *Ty,
llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag,
const Type *Ty,
QualType PointeeTy,
- llvm::DICompileUnit Unit) {
+ llvm::DIFile Unit) {
llvm::DIType EltTy = getOrCreateType(PointeeTy, Unit);
// Bit size, align and offset of the type.
@@ -284,17 +262,16 @@ llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag,
uint64_t Align = CGM.getContext().getTypeAlign(Ty);
return
- DebugFactory.CreateDerivedType(Tag, Unit, "", llvm::DICompileUnit(),
+ DebugFactory.CreateDerivedType(Tag, Unit, "", Unit,
0, Size, Align, 0, 0, EltTy);
}
llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,
- llvm::DICompileUnit Unit) {
+ llvm::DIFile Unit) {
if (BlockLiteralGenericSet)
return BlockLiteralGeneric;
- llvm::DICompileUnit DefUnit;
unsigned Tag = llvm::dwarf::DW_TAG_structure_type;
llvm::SmallVector<llvm::DIDescriptor, 5> EltTys;
@@ -314,7 +291,7 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,
FieldSize = CGM.getContext().getTypeSize(FType);
FieldAlign = CGM.getContext().getTypeAlign(FType);
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
- "reserved", DefUnit,
+ "reserved", Unit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
@@ -325,7 +302,7 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,
FieldSize = CGM.getContext().getTypeSize(FType);
FieldAlign = CGM.getContext().getTypeAlign(FType);
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
- "Size", DefUnit,
+ "Size", Unit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
@@ -337,7 +314,7 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,
unsigned Flags = llvm::DIType::FlagAppleBlock;
EltTy = DebugFactory.CreateCompositeType(Tag, Unit, "__block_descriptor",
- DefUnit, 0, FieldOffset, 0, 0, Flags,
+ Unit, 0, FieldOffset, 0, 0, Flags,
llvm::DIType(), Elements);
// Bit size, align and offset of the type.
@@ -345,7 +322,7 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,
uint64_t Align = CGM.getContext().getTypeAlign(Ty);
DescTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type,
- Unit, "", llvm::DICompileUnit(),
+ Unit, "", Unit,
0, Size, Align, 0, 0, EltTy);
FieldOffset = 0;
@@ -354,7 +331,7 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,
FieldSize = CGM.getContext().getTypeSize(FType);
FieldAlign = CGM.getContext().getTypeAlign(FType);
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
- "__isa", DefUnit,
+ "__isa", Unit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
@@ -365,7 +342,7 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,
FieldSize = CGM.getContext().getTypeSize(FType);
FieldAlign = CGM.getContext().getTypeAlign(FType);
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
- "__flags", DefUnit,
+ "__flags", Unit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
@@ -376,7 +353,7 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,
FieldSize = CGM.getContext().getTypeSize(FType);
FieldAlign = CGM.getContext().getTypeAlign(FType);
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
- "__reserved", DefUnit,
+ "__reserved", Unit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
@@ -387,7 +364,7 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,
FieldSize = CGM.getContext().getTypeSize(FType);
FieldAlign = CGM.getContext().getTypeAlign(FType);
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
- "__FuncPtr", DefUnit,
+ "__FuncPtr", Unit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
@@ -398,7 +375,7 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,
FieldSize = CGM.getContext().getTypeSize(Ty);
FieldAlign = CGM.getContext().getTypeAlign(Ty);
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
- "__descriptor", DefUnit,
+ "__descriptor", Unit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
@@ -407,19 +384,19 @@ llvm::DIType CGDebugInfo::CreateType(const BlockPointerType *Ty,
Elements = DebugFactory.GetOrCreateArray(EltTys.data(), EltTys.size());
EltTy = DebugFactory.CreateCompositeType(Tag, Unit, "__block_literal_generic",
- DefUnit, 0, FieldOffset, 0, 0, Flags,
+ Unit, 0, FieldOffset, 0, 0, Flags,
llvm::DIType(), Elements);
BlockLiteralGenericSet = true;
BlockLiteralGeneric
= DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type, Unit,
- "", llvm::DICompileUnit(),
+ "", Unit,
0, Size, Align, 0, 0, EltTy);
return BlockLiteralGeneric;
}
llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty,
- llvm::DICompileUnit Unit) {
+ llvm::DIFile Unit) {
// Typedefs are derived from some other type. If we have a typedef of a
// typedef, make sure to emit the whole chain.
llvm::DIType Src = getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit);
@@ -442,7 +419,7 @@ llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty,
}
llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty,
- llvm::DICompileUnit Unit) {
+ llvm::DIFile Unit) {
llvm::SmallVector<llvm::DIDescriptor, 16> EltTys;
// Add the result type at least.
@@ -462,7 +439,7 @@ llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty,
llvm::DIType DbgTy =
DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type,
- Unit, "", llvm::DICompileUnit(),
+ Unit, "", Unit,
0, 0, 0, 0, 0,
llvm::DIType(), EltTypeArray);
return DbgTy;
@@ -471,7 +448,7 @@ llvm::DIType CGDebugInfo::CreateType(const FunctionType *Ty,
/// CollectRecordFields - A helper function to collect debug info for
/// record fields. This is used while creating debug info entry for a Record.
void CGDebugInfo::
-CollectRecordFields(const RecordDecl *RD, llvm::DICompileUnit Unit,
+CollectRecordFields(const RecordDecl *RD, llvm::DIFile Unit,
llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys) {
unsigned FieldNo = 0;
SourceManager &SM = CGM.getContext().getSourceManager();
@@ -491,11 +468,11 @@ CollectRecordFields(const RecordDecl *RD, llvm::DICompileUnit Unit,
// Get the location for the field.
SourceLocation FieldDefLoc = Field->getLocation();
PresumedLoc PLoc = SM.getPresumedLoc(FieldDefLoc);
- llvm::DICompileUnit FieldDefUnit;
+ llvm::DIFile FieldDefUnit;
unsigned FieldLine = 0;
if (!PLoc.isInvalid()) {
- FieldDefUnit = getOrCreateCompileUnit(FieldDefLoc);
+ FieldDefUnit = getOrCreateFile(FieldDefLoc);
FieldLine = PLoc.getLine();
}
@@ -531,7 +508,7 @@ CollectRecordFields(const RecordDecl *RD, llvm::DICompileUnit Unit,
/// routine to get a method type which includes "this" pointer.
llvm::DIType
CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,
- llvm::DICompileUnit Unit) {
+ llvm::DIFile Unit) {
llvm::DIType FnTy = getOrCreateType(Method->getType(), Unit);
// Static methods do not need "this" pointer argument.
@@ -566,7 +543,7 @@ CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,
return
DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type,
- Unit, "", llvm::DICompileUnit(),
+ Unit, "", Unit,
0, 0, 0, 0, 0,
llvm::DIType(), EltTypeArray);
}
@@ -575,7 +552,7 @@ CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,
/// a single member function GlobalDecl.
llvm::DISubprogram
CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method,
- llvm::DICompileUnit Unit,
+ llvm::DIFile Unit,
llvm::DICompositeType &RecordTy) {
bool IsCtorOrDtor =
isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);
@@ -594,11 +571,11 @@ CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method,
// Get the location for the method.
SourceLocation MethodDefLoc = Method->getLocation();
PresumedLoc PLoc = SM.getPresumedLoc(MethodDefLoc);
- llvm::DICompileUnit MethodDefUnit;
+ llvm::DIFile MethodDefUnit;
unsigned MethodLine = 0;
if (!PLoc.isInvalid()) {
- MethodDefUnit = getOrCreateCompileUnit(MethodDefLoc);
+ MethodDefUnit = getOrCreateFile(MethodDefLoc);
MethodLine = PLoc.getLine();
}
@@ -640,7 +617,7 @@ CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method,
/// C++ member functions.This is used while creating debug info entry for
/// a Record.
void CGDebugInfo::
-CollectCXXMemberFunctions(const CXXRecordDecl *RD, llvm::DICompileUnit Unit,
+CollectCXXMemberFunctions(const CXXRecordDecl *RD, llvm::DIFile Unit,
llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys,
llvm::DICompositeType &RecordTy) {
for(CXXRecordDecl::method_iterator I = RD->method_begin(),
@@ -658,7 +635,7 @@ CollectCXXMemberFunctions(const CXXRecordDecl *RD, llvm::DICompileUnit Unit,
/// C++ base classes. This is used while creating debug info entry for
/// a Record.
void CGDebugInfo::
-CollectCXXBases(const CXXRecordDecl *RD, llvm::DICompileUnit Unit,
+CollectCXXBases(const CXXRecordDecl *RD, llvm::DIFile Unit,
llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys,
llvm::DICompositeType &RecordTy) {
@@ -688,7 +665,7 @@ CollectCXXBases(const CXXRecordDecl *RD, llvm::DICompileUnit Unit,
llvm::DIType DTy =
DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_inheritance,
RecordTy, llvm::StringRef(),
- llvm::DICompileUnit(), 0, 0, 0,
+ Unit, 0, 0, 0,
BaseOffset, BFlags,
getOrCreateType(BI->getType(),
Unit));
@@ -697,8 +674,8 @@ CollectCXXBases(const CXXRecordDecl *RD, llvm::DICompileUnit Unit,
}
/// getOrCreateVTablePtrType - Return debug info descriptor for vtable.
-llvm::DIType CGDebugInfo::getOrCreateVTablePtrType(llvm::DICompileUnit Unit) {
- if (!VTablePtrType.isNull())
+llvm::DIType CGDebugInfo::getOrCreateVTablePtrType(llvm::DIFile Unit) {
+ if (VTablePtrType.isValid())
return VTablePtrType;
ASTContext &Context = CGM.getContext();
@@ -710,18 +687,19 @@ llvm::DIType CGDebugInfo::getOrCreateVTablePtrType(llvm::DICompileUnit Unit) {
DebugFactory.GetOrCreateArray(STys.data(), STys.size());
llvm::DIType SubTy =
DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_subroutine_type,
- Unit, "", llvm::DICompileUnit(),
+ Unit, "", Unit,
0, 0, 0, 0, 0, llvm::DIType(), SElements);
unsigned Size = Context.getTypeSize(Context.VoidPtrTy);
llvm::DIType vtbl_ptr_type
= DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type,
- Unit, "__vtbl_ptr_type", llvm::DICompileUnit(),
+ Unit, "__vtbl_ptr_type", Unit,
0, Size, 0, 0, 0, SubTy);
- VTablePtrType = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type,
- Unit, "", llvm::DICompileUnit(),
- 0, Size, 0, 0, 0, vtbl_ptr_type);
+ VTablePtrType =
+ DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_pointer_type,
+ Unit, "", Unit,
+ 0, Size, 0, 0, 0, vtbl_ptr_type);
return VTablePtrType;
}
@@ -740,7 +718,7 @@ llvm::StringRef CGDebugInfo::getVtableName(const CXXRecordDecl *RD) {
/// CollectVtableInfo - If the C++ class has vtable info then insert appropriate
/// debug info entry in EltTys vector.
void CGDebugInfo::
-CollectVtableInfo(const CXXRecordDecl *RD, llvm::DICompileUnit Unit,
+CollectVtableInfo(const CXXRecordDecl *RD, llvm::DIFile Unit,
llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys) {
const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
@@ -755,7 +733,7 @@ CollectVtableInfo(const CXXRecordDecl *RD, llvm::DICompileUnit Unit,
unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
llvm::DIType VPTR
= DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
- getVtableName(RD), llvm::DICompileUnit(),
+ getVtableName(RD), Unit,
0, Size, 0, 0, 0,
getOrCreateVTablePtrType(Unit));
EltTys.push_back(VPTR);
@@ -763,7 +741,7 @@ CollectVtableInfo(const CXXRecordDecl *RD, llvm::DICompileUnit Unit,
/// CreateType - get structure or union type.
llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
- llvm::DICompileUnit Unit) {
+ llvm::DIFile Unit) {
RecordDecl *RD = Ty->getDecl();
unsigned Tag;
@@ -780,10 +758,10 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
// Get overall information about the record type for the debug info.
PresumedLoc PLoc = SM.getPresumedLoc(RD->getLocation());
- llvm::DICompileUnit DefUnit;
+ llvm::DIFile DefUnit;
unsigned Line = 0;
if (!PLoc.isInvalid()) {
- DefUnit = getOrCreateCompileUnit(RD->getLocation());
+ DefUnit = getOrCreateFile(RD->getLocation());
Line = PLoc.getLine();
}
@@ -796,12 +774,13 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
// A RD->getName() is not unique. However, the debug info descriptors
// are uniqued so use type name to ensure uniquness.
- std::string STy = QualType(Ty, 0).getAsString();
+ llvm::SmallString<256> FwdDeclName;
+ FwdDeclName.resize(256);
+ sprintf(&FwdDeclName[0], "fwd.type.%d", FwdDeclCount++);
llvm::DIDescriptor FDContext =
getContextDescriptor(dyn_cast<Decl>(RD->getDeclContext()), Unit);
llvm::DICompositeType FwdDecl =
- DebugFactory.CreateCompositeType(Tag, FDContext,
- STy.c_str(),
+ DebugFactory.CreateCompositeType(Tag, FDContext, FwdDeclName,
DefUnit, Line, 0, 0, 0, 0,
llvm::DIType(), llvm::DIArray());
@@ -861,19 +840,19 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
/// CreateType - get objective-c interface type.
llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
- llvm::DICompileUnit Unit) {
+ llvm::DIFile Unit) {
ObjCInterfaceDecl *ID = Ty->getDecl();
unsigned Tag = llvm::dwarf::DW_TAG_structure_type;
SourceManager &SM = CGM.getContext().getSourceManager();
// Get overall information about the record type for the debug info.
- llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(ID->getLocation());
+ llvm::DIFile DefUnit = getOrCreateFile(ID->getLocation());
PresumedLoc PLoc = SM.getPresumedLoc(ID->getLocation());
unsigned Line = PLoc.isInvalid() ? 0 : PLoc.getLine();
- unsigned RuntimeLang = DefUnit.getLanguage();
+ unsigned RuntimeLang = TheCU.getLanguage();
// To handle recursive interface, we
// first generate a debug descriptor for the struct as a forward declaration.
@@ -905,7 +884,7 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
getOrCreateType(CGM.getContext().getObjCInterfaceType(SClass), Unit);
llvm::DIType InhTag =
DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_inheritance,
- Unit, "", llvm::DICompileUnit(), 0, 0, 0,
+ Unit, "", Unit, 0, 0, 0,
0 /* offset */, 0, SClassTy);
EltTys.push_back(InhTag);
}
@@ -926,7 +905,7 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
// Get the location for the field.
SourceLocation FieldDefLoc = Field->getLocation();
- llvm::DICompileUnit FieldDefUnit = getOrCreateCompileUnit(FieldDefLoc);
+ llvm::DIFile FieldDefUnit = getOrCreateFile(FieldDefLoc);
PresumedLoc PLoc = SM.getPresumedLoc(FieldDefLoc);
unsigned FieldLine = PLoc.isInvalid() ? 0 : PLoc.getLine();
@@ -984,7 +963,7 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,
}
llvm::DIType CGDebugInfo::CreateType(const EnumType *Ty,
- llvm::DICompileUnit Unit) {
+ llvm::DIFile Unit) {
EnumDecl *ED = Ty->getDecl();
llvm::SmallVector<llvm::DIDescriptor, 32> Enumerators;
@@ -1002,7 +981,7 @@ llvm::DIType CGDebugInfo::CreateType(const EnumType *Ty,
DebugFactory.GetOrCreateArray(Enumerators.data(), Enumerators.size());
SourceLocation DefLoc = ED->getLocation();
- llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(DefLoc);
+ llvm::DIFile DefUnit = getOrCreateFile(DefLoc);
SourceManager &SM = CGM.getContext().getSourceManager();
PresumedLoc PLoc = SM.getPresumedLoc(DefLoc);
unsigned Line = PLoc.isInvalid() ? 0 : PLoc.getLine();
@@ -1025,7 +1004,7 @@ llvm::DIType CGDebugInfo::CreateType(const EnumType *Ty,
}
llvm::DIType CGDebugInfo::CreateType(const TagType *Ty,
- llvm::DICompileUnit Unit) {
+ llvm::DIFile Unit) {
if (const RecordType *RT = dyn_cast<RecordType>(Ty))
return CreateType(RT, Unit);
else if (const EnumType *ET = dyn_cast<EnumType>(Ty))
@@ -1035,7 +1014,7 @@ llvm::DIType CGDebugInfo::CreateType(const TagType *Ty,
}
llvm::DIType CGDebugInfo::CreateType(const VectorType *Ty,
- llvm::DICompileUnit Unit) {
+ llvm::DIFile Unit) {
llvm::DIType ElementTy = getOrCreateType(Ty->getElementType(), Unit);
uint64_t NumElems = Ty->getNumElements();
if (NumElems > 0)
@@ -1051,13 +1030,13 @@ llvm::DIType CGDebugInfo::CreateType(const VectorType *Ty,
return
DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_vector_type,
- Unit, "", llvm::DICompileUnit(),
+ Unit, "", Unit,
0, Size, Align, 0, 0,
ElementTy, SubscriptArray);
}
llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty,
- llvm::DICompileUnit Unit) {
+ llvm::DIFile Unit) {
uint64_t Size;
uint64_t Align;
@@ -1096,7 +1075,7 @@ llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty,
llvm::DIType DbgTy =
DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_array_type,
- Unit, "", llvm::DICompileUnit(),
+ Unit, "", Unit,
0, Size, Align, 0, 0,
getOrCreateType(EltTy, Unit),
SubscriptArray);
@@ -1104,13 +1083,13 @@ llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty,
}
llvm::DIType CGDebugInfo::CreateType(const LValueReferenceType *Ty,
- llvm::DICompileUnit Unit) {
+ llvm::DIFile Unit) {
return CreatePointerLikeType(llvm::dwarf::DW_TAG_reference_type,
Ty, Ty->getPointeeType(), Unit);
}
llvm::DIType CGDebugInfo::CreateType(const MemberPointerType *Ty,
- llvm::DICompileUnit U) {
+ llvm::DIFile U) {
QualType PointerDiffTy = CGM.getContext().getPointerDiffType();
llvm::DIType PointerDiffDITy = getOrCreateType(PointerDiffTy, U);
@@ -1129,14 +1108,14 @@ llvm::DIType CGDebugInfo::CreateType(const MemberPointerType *Ty,
// FIXME: This should probably be a function type instead.
ElementTypes[0] =
DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, U,
- "ptr", llvm::DICompileUnit(), 0,
+ "ptr", U, 0,
Info.first, Info.second, FieldOffset, 0,
PointerDiffDITy);
FieldOffset += Info.first;
ElementTypes[1] =
DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, U,
- "ptr", llvm::DICompileUnit(), 0,
+ "ptr", U, 0,
Info.first, Info.second, FieldOffset, 0,
PointerDiffDITy);
@@ -1146,7 +1125,7 @@ llvm::DIType CGDebugInfo::CreateType(const MemberPointerType *Ty,
return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_structure_type,
U, llvm::StringRef("test"),
- llvm::DICompileUnit(), 0, FieldOffset,
+ U, 0, FieldOffset,
0, 0, 0, llvm::DIType(), Elements);
}
@@ -1192,7 +1171,7 @@ static QualType UnwrapTypeForDebugInfo(QualType T) {
/// getOrCreateType - Get the type from the cache or create a new
/// one if necessary.
llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty,
- llvm::DICompileUnit Unit) {
+ llvm::DIFile Unit) {
if (Ty.isNull())
return llvm::DIType();
@@ -1218,7 +1197,7 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty,
/// CreateTypeNode - Create a new debug type node.
llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty,
- llvm::DICompileUnit Unit) {
+ llvm::DIFile Unit) {
// Handle qualifiers, which recursively handles what they refer to.
if (Ty.hasLocalQualifiers())
return CreateQualifiedType(Ty, Unit);
@@ -1267,6 +1246,7 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty,
case Type::MemberPointer:
return CreateType(cast<MemberPointerType>(Ty), Unit);
+ case Type::InjectedClassName:
case Type::TemplateSpecialization:
case Type::Elaborated:
case Type::QualifiedName:
@@ -1306,8 +1286,8 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,
llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator
FI = SPCache.find(FD);
if (FI != SPCache.end()) {
- llvm::DISubprogram SP(dyn_cast_or_null<llvm::MDNode>(FI->second));
- if (!SP.isNull() && SP.isSubprogram() && SP.isDefinition()) {
+ llvm::DIDescriptor SP(dyn_cast_or_null<llvm::MDNode>(FI->second));
+ if (SP.isSubprogram() && llvm::DISubprogram(SP.getNode()).isDefinition()) {
RegionStack.push_back(SP.getNode());
RegionMap[D] = llvm::WeakVH(SP.getNode());
return;
@@ -1329,7 +1309,7 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType,
// It is expected that CurLoc is set before using EmitFunctionStart.
// Usually, CurLoc points to the left bracket location of compound
// statement representing function body.
- llvm::DICompileUnit Unit = getOrCreateCompileUnit(CurLoc);
+ llvm::DIFile Unit = getOrCreateFile(CurLoc);
SourceManager &SM = CGM.getContext().getSourceManager();
unsigned LineNo = SM.getPresumedLoc(CurLoc).getLine();
@@ -1359,7 +1339,7 @@ void CGDebugInfo::EmitStopPoint(llvm::Function *Fn, CGBuilderTy &Builder) {
PrevLoc = CurLoc;
// Get the appropriate compile unit.
- llvm::DICompileUnit Unit = getOrCreateCompileUnit(CurLoc);
+ llvm::DIFile Unit = getOrCreateFile(CurLoc);
PresumedLoc PLoc = SM.getPresumedLoc(CurLoc);
llvm::DIDescriptor DR(RegionStack.back());
@@ -1406,7 +1386,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD,
uint64_t FieldSize, FieldOffset;
unsigned FieldAlign;
- llvm::DICompileUnit Unit = getOrCreateCompileUnit(VD->getLocation());
+ llvm::DIFile Unit = getOrCreateFile(VD->getLocation());
QualType Type = VD->getType();
FieldOffset = 0;
@@ -1415,7 +1395,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD,
FieldSize = CGM.getContext().getTypeSize(FType);
FieldAlign = CGM.getContext().getTypeAlign(FType);
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
- "__isa", llvm::DICompileUnit(),
+ "__isa", Unit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
@@ -1426,7 +1406,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD,
FieldSize = CGM.getContext().getTypeSize(FType);
FieldAlign = CGM.getContext().getTypeAlign(FType);
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
- "__forwarding", llvm::DICompileUnit(),
+ "__forwarding", Unit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
@@ -1437,7 +1417,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD,
FieldSize = CGM.getContext().getTypeSize(FType);
FieldAlign = CGM.getContext().getTypeAlign(FType);
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
- "__flags", llvm::DICompileUnit(),
+ "__flags", Unit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
@@ -1448,7 +1428,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD,
FieldSize = CGM.getContext().getTypeSize(FType);
FieldAlign = CGM.getContext().getTypeAlign(FType);
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
- "__size", llvm::DICompileUnit(),
+ "__size", Unit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
@@ -1461,8 +1441,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD,
FieldSize = CGM.getContext().getTypeSize(FType);
FieldAlign = CGM.getContext().getTypeAlign(FType);
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
- "__copy_helper",
- llvm::DICompileUnit(),
+ "__copy_helper", Unit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
@@ -1473,8 +1452,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD,
FieldSize = CGM.getContext().getTypeSize(FType);
FieldAlign = CGM.getContext().getTypeAlign(FType);
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
- "__destroy_helper",
- llvm::DICompileUnit(),
+ "__destroy_helper", Unit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
@@ -1497,7 +1475,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD,
FieldSize = CGM.getContext().getTypeSize(FType);
FieldAlign = CGM.getContext().getTypeAlign(FType);
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member,
- Unit, "", llvm::DICompileUnit(),
+ Unit, "", Unit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
@@ -1512,7 +1490,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD,
*XOffset = FieldOffset;
FieldTy = DebugFactory.CreateDerivedType(llvm::dwarf::DW_TAG_member, Unit,
- VD->getName(), llvm::DICompileUnit(),
+ VD->getName(), Unit,
0, FieldSize, FieldAlign,
FieldOffset, 0, FieldTy);
EltTys.push_back(FieldTy);
@@ -1524,8 +1502,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD,
unsigned Flags = llvm::DIType::FlagBlockByrefStruct;
return DebugFactory.CreateCompositeType(llvm::dwarf::DW_TAG_structure_type,
- Unit, "",
- llvm::DICompileUnit(),
+ Unit, "", Unit,
0, FieldOffset, 0, 0, Flags,
llvm::DIType(), Elements);
@@ -1542,7 +1519,7 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag,
if (CGO.OptimizationLevel)
return;
- llvm::DICompileUnit Unit = getOrCreateCompileUnit(VD->getLocation());
+ llvm::DIFile Unit = getOrCreateFile(VD->getLocation());
llvm::DIType Ty;
uint64_t XOffset = 0;
if (VD->hasAttr<BlocksAttr>())
@@ -1560,9 +1537,9 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag,
if (PLoc.isValid()) {
Line = PLoc.getLine();
Column = PLoc.getColumn();
- Unit = getOrCreateCompileUnit(CurLoc);
+ Unit = getOrCreateFile(CurLoc);
} else {
- Unit = llvm::DICompileUnit();
+ Unit = llvm::DIFile();
}
// Create the descriptor for the variable.
@@ -1596,7 +1573,7 @@ void CGDebugInfo::EmitDeclare(const BlockDeclRefExpr *BDRE, unsigned Tag,
return;
uint64_t XOffset = 0;
- llvm::DICompileUnit Unit = getOrCreateCompileUnit(VD->getLocation());
+ llvm::DIFile Unit = getOrCreateFile(VD->getLocation());
llvm::DIType Ty;
if (VD->hasAttr<BlocksAttr>())
Ty = EmitTypeForVarWithBlocksAttr(VD, &XOffset);
@@ -1610,7 +1587,7 @@ void CGDebugInfo::EmitDeclare(const BlockDeclRefExpr *BDRE, unsigned Tag,
if (!PLoc.isInvalid())
Line = PLoc.getLine();
else
- Unit = llvm::DICompileUnit();
+ Unit = llvm::DIFile();
CharUnits offset = CGF->BlockDecls[VD];
llvm::SmallVector<llvm::Value *, 9> addr;
@@ -1675,7 +1652,7 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
const VarDecl *D) {
// Create global variable debug descriptor.
- llvm::DICompileUnit Unit = getOrCreateCompileUnit(D->getLocation());
+ llvm::DIFile Unit = getOrCreateFile(D->getLocation());
SourceManager &SM = CGM.getContext().getSourceManager();
PresumedLoc PLoc = SM.getPresumedLoc(D->getLocation());
unsigned LineNo = PLoc.isInvalid() ? 0 : PLoc.getLine();
@@ -1706,7 +1683,7 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
ObjCInterfaceDecl *ID) {
// Create global variable debug descriptor.
- llvm::DICompileUnit Unit = getOrCreateCompileUnit(ID->getLocation());
+ llvm::DIFile Unit = getOrCreateFile(ID->getLocation());
SourceManager &SM = CGM.getContext().getSourceManager();
PresumedLoc PLoc = SM.getPresumedLoc(ID->getLocation());
unsigned LineNo = PLoc.isInvalid() ? 0 : PLoc.getLine();
@@ -1750,7 +1727,7 @@ CGDebugInfo::getOrCreateNameSpace(const NamespaceDecl *NSDecl,
getContextDescriptor(dyn_cast<Decl>(NSDecl->getDeclContext()), Unit);
llvm::DINameSpace NS =
DebugFactory.CreateNameSpace(Context, NSDecl->getName(),
- llvm::DICompileUnit(Unit.getNode()), LineNo);
+ llvm::DIFile(Unit.getNode()), LineNo);
NameSpaceCache[NSDecl] = llvm::WeakVH(NS.getNode());
return NS;
}
diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h
index 50f5759..47a4620 100644
--- a/lib/CodeGen/CGDebugInfo.h
+++ b/lib/CodeGen/CGDebugInfo.h
@@ -43,16 +43,14 @@ namespace CodeGen {
/// the backend.
class CGDebugInfo {
CodeGenModule &CGM;
- bool isMainCompileUnitCreated;
llvm::DIFactory DebugFactory;
-
+ llvm::DICompileUnit TheCU;
SourceLocation CurLoc, PrevLoc;
-
llvm::DIType VTablePtrType;
-
- /// CompileUnitCache - Cache of previously constructed CompileUnits.
- llvm::DenseMap<unsigned, llvm::DICompileUnit> CompileUnitCache;
-
+ /// FwdDeclCount - This counter is used to ensure unique names for forward
+ /// record decls.
+ unsigned FwdDeclCount;
+
/// TypeCache - Cache of previously constructed Types.
// FIXME: Eliminate this map. Be careful of iterator invalidation.
std::map<void *, llvm::WeakVH> TypeCache;
@@ -71,52 +69,52 @@ class CGDebugInfo {
llvm::DenseMap<const NamespaceDecl *, llvm::WeakVH> NameSpaceCache;
/// Helper functions for getOrCreateType.
- llvm::DIType CreateType(const BuiltinType *Ty, llvm::DICompileUnit U);
- llvm::DIType CreateType(const ComplexType *Ty, llvm::DICompileUnit U);
- llvm::DIType CreateQualifiedType(QualType Ty, llvm::DICompileUnit U);
- llvm::DIType CreateType(const TypedefType *Ty, llvm::DICompileUnit U);
+ llvm::DIType CreateType(const BuiltinType *Ty, llvm::DIFile F);
+ llvm::DIType CreateType(const ComplexType *Ty, llvm::DIFile F);
+ llvm::DIType CreateQualifiedType(QualType Ty, llvm::DIFile F);
+ llvm::DIType CreateType(const TypedefType *Ty, llvm::DIFile F);
llvm::DIType CreateType(const ObjCObjectPointerType *Ty,
- llvm::DICompileUnit Unit);
- llvm::DIType CreateType(const PointerType *Ty, llvm::DICompileUnit U);
- llvm::DIType CreateType(const BlockPointerType *Ty, llvm::DICompileUnit U);
- llvm::DIType CreateType(const FunctionType *Ty, llvm::DICompileUnit U);
- llvm::DIType CreateType(const TagType *Ty, llvm::DICompileUnit U);
- llvm::DIType CreateType(const RecordType *Ty, llvm::DICompileUnit U);
- llvm::DIType CreateType(const ObjCInterfaceType *Ty, llvm::DICompileUnit U);
- llvm::DIType CreateType(const EnumType *Ty, llvm::DICompileUnit U);
- llvm::DIType CreateType(const VectorType *Ty, llvm::DICompileUnit Unit);
- llvm::DIType CreateType(const ArrayType *Ty, llvm::DICompileUnit U);
- llvm::DIType CreateType(const LValueReferenceType *Ty, llvm::DICompileUnit U);
- llvm::DIType CreateType(const MemberPointerType *Ty, llvm::DICompileUnit U);
+ llvm::DIFile F);
+ llvm::DIType CreateType(const PointerType *Ty, llvm::DIFile F);
+ llvm::DIType CreateType(const BlockPointerType *Ty, llvm::DIFile F);
+ llvm::DIType CreateType(const FunctionType *Ty, llvm::DIFile F);
+ llvm::DIType CreateType(const TagType *Ty, llvm::DIFile F);
+ llvm::DIType CreateType(const RecordType *Ty, llvm::DIFile F);
+ llvm::DIType CreateType(const ObjCInterfaceType *Ty, llvm::DIFile F);
+ llvm::DIType CreateType(const EnumType *Ty, llvm::DIFile F);
+ llvm::DIType CreateType(const VectorType *Ty, llvm::DIFile F);
+ llvm::DIType CreateType(const ArrayType *Ty, llvm::DIFile F);
+ llvm::DIType CreateType(const LValueReferenceType *Ty, llvm::DIFile F);
+ llvm::DIType CreateType(const MemberPointerType *Ty, llvm::DIFile F);
llvm::DIType getOrCreateMethodType(const CXXMethodDecl *Method,
- llvm::DICompileUnit Unit);
- llvm::DIType getOrCreateVTablePtrType(llvm::DICompileUnit Unit);
+ llvm::DIFile F);
+ llvm::DIType getOrCreateVTablePtrType(llvm::DIFile F);
llvm::DINameSpace getOrCreateNameSpace(const NamespaceDecl *N,
llvm::DIDescriptor Unit);
llvm::DIType CreatePointerLikeType(unsigned Tag,
const Type *Ty, QualType PointeeTy,
- llvm::DICompileUnit U);
+ llvm::DIFile F);
llvm::DISubprogram CreateCXXMemberFunction(const CXXMethodDecl *Method,
- llvm::DICompileUnit Unit,
+ llvm::DIFile F,
llvm::DICompositeType &RecordTy);
void CollectCXXMemberFunctions(const CXXRecordDecl *Decl,
- llvm::DICompileUnit U,
+ llvm::DIFile F,
llvm::SmallVectorImpl<llvm::DIDescriptor> &E,
llvm::DICompositeType &T);
void CollectCXXBases(const CXXRecordDecl *Decl,
- llvm::DICompileUnit Unit,
+ llvm::DIFile F,
llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys,
llvm::DICompositeType &RecordTy);
- void CollectRecordFields(const RecordDecl *Decl, llvm::DICompileUnit U,
+ void CollectRecordFields(const RecordDecl *Decl, llvm::DIFile F,
llvm::SmallVectorImpl<llvm::DIDescriptor> &E);
void CollectVtableInfo(const CXXRecordDecl *Decl,
- llvm::DICompileUnit Unit,
+ llvm::DIFile F,
llvm::SmallVectorImpl<llvm::DIDescriptor> &EltTys);
public:
@@ -185,16 +183,19 @@ private:
llvm::DIDescriptor getContextDescriptor(const Decl *Decl,
llvm::DIDescriptor &CU);
- /// getOrCreateCompileUnit - Get the compile unit from the cache or create a
- /// new one if necessary.
- llvm::DICompileUnit getOrCreateCompileUnit(SourceLocation Loc);
+ /// CreateCompileUnit - Create new compile unit.
+ void CreateCompileUnit();
+
+ /// getOrCreateFile - Get the file debug info descriptor for the input
+ /// location.
+ llvm::DIFile getOrCreateFile(SourceLocation Loc);
/// getOrCreateType - Get the type from the cache or create a new type if
/// necessary.
- llvm::DIType getOrCreateType(QualType Ty, llvm::DICompileUnit Unit);
+ llvm::DIType getOrCreateType(QualType Ty, llvm::DIFile F);
/// CreateTypeNode - Create type metadata for a source language type.
- llvm::DIType CreateTypeNode(QualType Ty, llvm::DICompileUnit Unit);
+ llvm::DIType CreateTypeNode(QualType Ty, llvm::DIFile F);
/// getFunctionName - Get function name for the given FunctionDecl. If the
/// name is constructred on demand (e.g. C++ destructor) then the name
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index ac189a0..4847ca3 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -178,6 +178,11 @@ void AggExprEmitter::EmitFinalDestCopy(const Expr *E, LValue Src, bool Ignore) {
//===----------------------------------------------------------------------===//
void AggExprEmitter::VisitCastExpr(CastExpr *E) {
+ if (!DestPtr) {
+ Visit(E->getSubExpr());
+ return;
+ }
+
switch (E->getCastKind()) {
default: assert(0 && "Unhandled cast kind!");
@@ -205,6 +210,11 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
break;
case CastExpr::CK_NullToMemberPointer: {
+ // If the subexpression's type is the C++0x nullptr_t, emit the
+ // subexpression, which may have side effects.
+ if (E->getSubExpr()->getType()->isNullPtrType())
+ Visit(E->getSubExpr());
+
const llvm::Type *PtrDiffTy =
CGF.ConvertType(CGF.getContext().getPointerDiffType());
@@ -652,6 +662,16 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
return;
}
+
+ // If we're initializing the whole aggregate, just do it in place.
+ // FIXME: This is a hack around an AST bug (PR6537).
+ if (NumInitElements == 1 && E->getType() == E->getInit(0)->getType()) {
+ EmitInitializationToLValue(E->getInit(0),
+ LValue::MakeAddr(DestPtr, Qualifiers()),
+ E->getType());
+ return;
+ }
+
// Here we iterate over the fields; this makes it simpler to both
// default-initialize fields and skip over unnamed fields.
@@ -670,8 +690,8 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
// We never generate write-barries for initialized fields.
LValue::SetObjCNonGC(FieldLoc, true);
if (CurInitVal < NumInitElements) {
- // Store the initializer into the field
- EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc,
+ // Store the initializer into the field.
+ EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc,
Field->getType());
} else {
// We're out of initalizers; default-initialize to null
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index b62e6ed..3ff77f0 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -59,7 +59,7 @@ RValue CodeGenFunction::EmitObjCMessageExpr(const ObjCMessageExpr *E) {
// Find the receiver
llvm::Value *Receiver;
if (!ReceiverExpr) {
- const ObjCInterfaceDecl *OID = E->getClassInfo().first;
+ const ObjCInterfaceDecl *OID = E->getClassInfo().Decl;
// Very special case, super send in class method. The receiver is
// self (the class object) and the send uses super semantics.
diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp
index 932bd07..4500ec0 100644
--- a/lib/CodeGen/CGVtable.cpp
+++ b/lib/CodeGen/CGVtable.cpp
@@ -60,10 +60,13 @@ public:
/// Method - The method decl of the overrider.
const CXXMethodDecl *Method;
- /// Offset - the base offset of the overrider relative to the layout class.
- int64_t Offset;
+ /// Offset - the base offset of the overrider in the layout class.
+ uint64_t Offset;
- OverriderInfo() : Method(0), Offset(0) { }
+ /// OldOffset - FIXME: Remove this.
+ int64_t OldOffset;
+
+ OverriderInfo() : Method(0), Offset(0), OldOffset(0) { }
};
private:
@@ -71,6 +74,16 @@ private:
/// are stored.
const CXXRecordDecl *MostDerivedClass;
+ /// MostDerivedClassOffset - If we're building final overriders for a
+ /// construction vtable, this holds the offset from the layout class to the
+ /// most derived class.
+ const uint64_t MostDerivedClassOffset;
+
+ /// LayoutClass - The class we're using for layout information. Will be
+ /// different than the most derived class if the final overriders are for a
+ /// construction vtable.
+ const CXXRecordDecl *LayoutClass;
+
ASTContext &Context;
/// MostDerivedClassLayout - the AST record layout of the most derived class.
@@ -122,11 +135,13 @@ private:
/// subobject (and all its direct and indirect bases).
void ComputeFinalOverriders(BaseSubobject Base,
bool BaseSubobjectIsVisitedVBase,
+ uint64_t OffsetInLayoutClass,
SubobjectOffsetsMapTy &Offsets);
/// AddOverriders - Add the final overriders for this base subobject to the
/// map of final overriders.
- void AddOverriders(BaseSubobject Base, SubobjectOffsetsMapTy &Offsets);
+ void AddOverriders(BaseSubobject Base,uint64_t OffsetInLayoutClass,
+ SubobjectOffsetsMapTy &Offsets);
/// PropagateOverrider - Propagate the NewMD overrider to all the functions
/// that OldMD overrides. For example, if we have:
@@ -139,6 +154,7 @@ private:
/// C::f.
void PropagateOverrider(const CXXMethodDecl *OldMD,
BaseSubobject NewBase,
+ uint64_t OverriderOffsetInLayoutClass,
const CXXMethodDecl *NewMD,
SubobjectOffsetsMapTy &Offsets);
@@ -146,7 +162,9 @@ private:
SubobjectOffsetsMapTy &Offsets);
public:
- explicit FinalOverriders(const CXXRecordDecl *MostDerivedClass);
+ FinalOverriders(const CXXRecordDecl *MostDerivedClass,
+ uint64_t MostDerivedClassOffset,
+ const CXXRecordDecl *LayoutClass);
/// getOverrider - Get the final overrider for the given method declaration in
/// the given base subobject.
@@ -181,15 +199,19 @@ public:
#define DUMP_OVERRIDERS 0
-FinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass)
+FinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass,
+ uint64_t MostDerivedClassOffset,
+ const CXXRecordDecl *LayoutClass)
: MostDerivedClass(MostDerivedClass),
+ MostDerivedClassOffset(MostDerivedClassOffset), LayoutClass(LayoutClass),
Context(MostDerivedClass->getASTContext()),
MostDerivedClassLayout(Context.getASTRecordLayout(MostDerivedClass)) {
// Compute the final overriders.
SubobjectOffsetsMapTy Offsets;
ComputeFinalOverriders(BaseSubobject(MostDerivedClass, 0),
- /*BaseSubobjectIsVisitedVBase=*/false, Offsets);
+ /*BaseSubobjectIsVisitedVBase=*/false,
+ MostDerivedClassOffset, Offsets);
VisitedVirtualBases.clear();
#if DUMP_OVERRIDERS
@@ -199,18 +221,19 @@ FinalOverriders::FinalOverriders(const CXXRecordDecl *MostDerivedClass)
// Also dump the base offsets (for now).
for (SubobjectOffsetsMapTy::const_iterator I = Offsets.begin(),
E = Offsets.end(); I != E; ++I) {
- const OffsetVectorTy& OffsetVector = I->second;
+ const OffsetSetVectorTy& OffsetSetVector = I->second;
llvm::errs() << "Base offsets for ";
llvm::errs() << I->first->getQualifiedNameAsString() << '\n';
- for (unsigned I = 0, E = OffsetVector.size(); I != E; ++I)
- llvm::errs() << " " << I << " - " << OffsetVector[I] << '\n';
+ for (unsigned I = 0, E = OffsetSetVector.size(); I != E; ++I)
+ llvm::errs() << " " << I << " - " << OffsetSetVector[I] / 8 << '\n';
}
#endif
}
void FinalOverriders::AddOverriders(BaseSubobject Base,
+ uint64_t OffsetInLayoutClass,
SubobjectOffsetsMapTy &Offsets) {
const CXXRecordDecl *RD = Base.getBase();
@@ -222,13 +245,14 @@ void FinalOverriders::AddOverriders(BaseSubobject Base,
continue;
// First, propagate the overrider.
- PropagateOverrider(MD, Base, MD, Offsets);
+ PropagateOverrider(MD, Base, OffsetInLayoutClass, MD, Offsets);
// Add the overrider as the final overrider of itself.
OverriderInfo& Overrider = OverridersMap[std::make_pair(Base, MD)];
assert(!Overrider.Method && "Overrider should not exist yet!");
- Overrider.Offset = Base.getBaseOffset();
+ Overrider.OldOffset = Base.getBaseOffset();
+ Overrider.Offset = OffsetInLayoutClass;
Overrider.Method = MD;
}
}
@@ -346,6 +370,7 @@ ComputeReturnAdjustmentBaseOffset(ASTContext &Context,
void FinalOverriders::PropagateOverrider(const CXXMethodDecl *OldMD,
BaseSubobject NewBase,
+ uint64_t OverriderOffsetInLayoutClass,
const CXXMethodDecl *NewMD,
SubobjectOffsetsMapTy &Offsets) {
for (CXXMethodDecl::method_iterator I = OldMD->begin_overridden_methods(),
@@ -389,11 +414,13 @@ void FinalOverriders::PropagateOverrider(const CXXMethodDecl *OldMD,
}
// Set the new overrider.
- Overrider.Offset = NewBase.getBaseOffset();
+ Overrider.Offset = OverriderOffsetInLayoutClass;
+ Overrider.OldOffset = NewBase.getBaseOffset();
Overrider.Method = NewMD;
// And propagate it further.
- PropagateOverrider(OverriddenMD, NewBase, NewMD, Offsets);
+ PropagateOverrider(OverriddenMD, NewBase, OverriderOffsetInLayoutClass,
+ NewMD, Offsets);
}
}
}
@@ -416,6 +443,7 @@ FinalOverriders::MergeSubobjectOffsets(const SubobjectOffsetsMapTy &NewOffsets,
void FinalOverriders::ComputeFinalOverriders(BaseSubobject Base,
bool BaseSubobjectIsVisitedVBase,
+ uint64_t OffsetInLayoutClass,
SubobjectOffsetsMapTy &Offsets) {
const CXXRecordDecl *RD = Base.getBase();
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
@@ -433,12 +461,20 @@ void FinalOverriders::ComputeFinalOverriders(BaseSubobject Base,
bool IsVisitedVirtualBase = BaseSubobjectIsVisitedVBase;
uint64_t BaseOffset;
+ uint64_t BaseOffsetInLayoutClass;
if (I->isVirtual()) {
if (!VisitedVirtualBases.insert(BaseDecl))
IsVisitedVirtualBase = true;
BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(BaseDecl);
+
+ const ASTRecordLayout &LayoutClassLayout =
+ Context.getASTRecordLayout(LayoutClass);
+ BaseOffsetInLayoutClass =
+ LayoutClassLayout.getVBaseClassOffset(BaseDecl);
} else {
BaseOffset = Layout.getBaseClassOffset(BaseDecl) + Base.getBaseOffset();
+ BaseOffsetInLayoutClass = Layout.getBaseClassOffset(BaseDecl) +
+ OffsetInLayoutClass;
}
// Compute the final overriders for this base.
@@ -463,13 +499,14 @@ void FinalOverriders::ComputeFinalOverriders(BaseSubobject Base,
// Here, we still want to compute the overriders for A as a base of C,
// because otherwise we'll miss that C::g overrides A::f.
ComputeFinalOverriders(BaseSubobject(BaseDecl, BaseOffset),
- IsVisitedVirtualBase, NewOffsets);
+ IsVisitedVirtualBase, BaseOffsetInLayoutClass,
+ NewOffsets);
}
/// Now add the overriders for this particular subobject.
/// (We don't want to do this more than once for a virtual base).
if (!BaseSubobjectIsVisitedVBase)
- AddOverriders(Base, NewOffsets);
+ AddOverriders(Base, OffsetInLayoutClass, NewOffsets);
// And merge the newly discovered subobject offsets.
MergeSubobjectOffsets(NewOffsets, Offsets);
@@ -508,7 +545,7 @@ void FinalOverriders::dump(llvm::raw_ostream &Out, BaseSubobject Base) {
}
Out << "Final overriders for (" << RD->getQualifiedNameAsString() << ", ";
- Out << Base.getBaseOffset() << ")\n";
+ Out << Base.getBaseOffset() / 8 << ")\n";
// Now dump the overriders for this base subobject.
for (CXXRecordDecl::method_iterator I = RD->method_begin(),
@@ -522,7 +559,7 @@ void FinalOverriders::dump(llvm::raw_ostream &Out, BaseSubobject Base) {
Out << " " << MD->getQualifiedNameAsString() << " - (";
Out << Overrider.Method->getQualifiedNameAsString();
- Out << ", " << Overrider.Offset << ')';
+ Out << ", " << Overrider.OldOffset / 8 << ", " << Overrider.Offset / 8 << ')';
AdjustmentOffsetsMapTy::const_iterator AI =
ReturnAdjustments.find(std::make_pair(Base, MD));
@@ -1173,15 +1210,17 @@ private:
/// thunk. Since we require that a call to C::f() first convert to A*,
/// C-in-D's copy of A's vtable is never referenced, so this is not
/// necessary.
- bool IsOverriderUsed(BaseSubobject Base,
- BaseSubobject FirstBaseInPrimaryBaseChain,
- uint64_t OffsetInLayoutClass,
- FinalOverriders::OverriderInfo Overrider) const;
+ bool IsOverriderUsed(const CXXMethodDecl *Overrider,
+ uint64_t BaseOffsetInLayoutClass,
+ const CXXRecordDecl *FirstBaseInPrimaryBaseChain,
+ uint64_t FirstBaseOffsetInLayoutClass) const;
+
/// AddMethods - Add the methods of this base subobject and all its
/// primary bases to the vtable components vector.
- void AddMethods(BaseSubobject Base, BaseSubobject FirstBaseInPrimaryBaseChain,
- uint64_t OffsetInLayoutClass,
+ void AddMethods(BaseSubobject Base, uint64_t BaseOffsetInLayoutClass,
+ const CXXRecordDecl *FirstBaseInPrimaryBaseChain,
+ uint64_t FirstBaseOffsetInLayoutClass,
PrimaryBasesSetVectorTy &PrimaryBases);
// LayoutVtable - Layout the vtable for the given base class, including its
@@ -1201,6 +1240,7 @@ private:
/// DeterminePrimaryVirtualBases - Determine the primary virtual bases in this
/// class hierarchy.
void DeterminePrimaryVirtualBases(const CXXRecordDecl *RD,
+ uint64_t OffsetInLayoutClass,
VisitedVirtualBasesSetTy &VBases);
/// LayoutVtablesForVirtualBases - Layout vtables for all virtual bases of the
@@ -1222,7 +1262,7 @@ public:
MostDerivedClassOffset(MostDerivedClassOffset),
MostDerivedClassIsVirtual(MostDerivedClassIsVirtual),
LayoutClass(LayoutClass), Context(MostDerivedClass->getASTContext()),
- Overriders(MostDerivedClass) {
+ Overriders(MostDerivedClass, MostDerivedClassOffset, LayoutClass) {
LayoutVtable();
}
@@ -1269,7 +1309,7 @@ void VtableBuilder::ComputeThisAdjustments() {
Overriders.getOverrider(OverriddenBaseSubobject, MD);
// Check if we need an adjustment.
- if (Overrider.Offset == (int64_t)MethodInfo.BaseOffset)
+ if (Overrider.OldOffset == (int64_t)MethodInfo.BaseOffset)
continue;
uint64_t VtableIndex = MethodInfo.VtableIndex;
@@ -1284,7 +1324,7 @@ void VtableBuilder::ComputeThisAdjustments() {
continue;
BaseSubobject OverriderBaseSubobject(Overrider.Method->getParent(),
- Overrider.Offset);
+ Overrider.OldOffset);
// Compute the adjustment offset.
BaseOffset ThisAdjustmentOffset =
@@ -1473,13 +1513,13 @@ OverridesIndirectMethodInBases(const CXXMethodDecl *MD,
}
bool
-VtableBuilder::IsOverriderUsed(BaseSubobject Base,
- BaseSubobject FirstBaseInPrimaryBaseChain,
- uint64_t OffsetInLayoutClass,
- FinalOverriders::OverriderInfo Overrider) const {
+VtableBuilder::IsOverriderUsed(const CXXMethodDecl *Overrider,
+ uint64_t BaseOffsetInLayoutClass,
+ const CXXRecordDecl *FirstBaseInPrimaryBaseChain,
+ uint64_t FirstBaseOffsetInLayoutClass) const {
// If the base and the first base in the primary base chain have the same
// offsets, then this overrider will be used.
- if (Base.getBaseOffset() == OffsetInLayoutClass)
+ if (BaseOffsetInLayoutClass == FirstBaseOffsetInLayoutClass)
return true;
// We know now that Base (or a direct or indirect base of it) is a primary
@@ -1488,12 +1528,12 @@ VtableBuilder::IsOverriderUsed(BaseSubobject Base,
// If the overrider is the first base in the primary base chain, we know
// that the overrider will be used.
- if (Overrider.Method->getParent() == FirstBaseInPrimaryBaseChain.getBase())
+ if (Overrider->getParent() == FirstBaseInPrimaryBaseChain)
return true;
VtableBuilder::PrimaryBasesSetVectorTy PrimaryBases;
- const CXXRecordDecl *RD = FirstBaseInPrimaryBaseChain.getBase();
+ const CXXRecordDecl *RD = FirstBaseInPrimaryBaseChain;
PrimaryBases.insert(RD);
// Now traverse the base chain, starting with the first base, until we find
@@ -1515,7 +1555,7 @@ VtableBuilder::IsOverriderUsed(BaseSubobject Base,
// Now check if this is the primary base that is not a primary base in the
// most derived class.
if (LayoutClassLayout.getVBaseClassOffset(PrimaryBase) !=
- OffsetInLayoutClass) {
+ FirstBaseOffsetInLayoutClass) {
// We found it, stop walking the chain.
break;
}
@@ -1532,7 +1572,7 @@ VtableBuilder::IsOverriderUsed(BaseSubobject Base,
// If the final overrider is an override of one of the primary bases,
// then we know that it will be used.
- return OverridesIndirectMethodInBases(Overrider.Method, PrimaryBases);
+ return OverridesIndirectMethodInBases(Overrider, PrimaryBases);
}
/// FindNearestOverriddenMethod - Given a method, returns the overridden method
@@ -1557,17 +1597,17 @@ FindNearestOverriddenMethod(const CXXMethodDecl *MD,
return 0;
}
-void
-VtableBuilder::AddMethods(BaseSubobject Base,
- BaseSubobject FirstBaseInPrimaryBaseChain,
- uint64_t OffsetInLayoutClass,
+void
+VtableBuilder::AddMethods(BaseSubobject Base, uint64_t BaseOffsetInLayoutClass,
+ const CXXRecordDecl *FirstBaseInPrimaryBaseChain,
+ uint64_t FirstBaseOffsetInLayoutClass,
PrimaryBasesSetVectorTy &PrimaryBases) {
const CXXRecordDecl *RD = Base.getBase();
-
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
if (const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase()) {
- uint64_t BaseOffset;
+ uint64_t PrimaryBaseOffset;
+ uint64_t PrimaryBaseOffsetInLayoutClass;
if (Layout.getPrimaryBaseWasVirtual()) {
assert(Layout.getVBaseClassOffset(PrimaryBase) == 0 &&
"Primary vbase should have a zero offset!");
@@ -1575,17 +1615,25 @@ VtableBuilder::AddMethods(BaseSubobject Base,
const ASTRecordLayout &MostDerivedClassLayout =
Context.getASTRecordLayout(MostDerivedClass);
- BaseOffset = MostDerivedClassLayout.getVBaseClassOffset(PrimaryBase);
+ PrimaryBaseOffset =
+ MostDerivedClassLayout.getVBaseClassOffset(PrimaryBase);
+
+ const ASTRecordLayout &LayoutClassLayout =
+ Context.getASTRecordLayout(LayoutClass);
+
+ PrimaryBaseOffsetInLayoutClass =
+ LayoutClassLayout.getVBaseClassOffset(PrimaryBase);
} else {
assert(Layout.getBaseClassOffset(PrimaryBase) == 0 &&
"Primary base should have a zero offset!");
- BaseOffset = Base.getBaseOffset();
+ PrimaryBaseOffset = Base.getBaseOffset();
+ PrimaryBaseOffsetInLayoutClass = BaseOffsetInLayoutClass;
}
- // FIXME: OffsetInLayoutClass is not right here.
- AddMethods(BaseSubobject(PrimaryBase, BaseOffset),
- FirstBaseInPrimaryBaseChain, OffsetInLayoutClass, PrimaryBases);
+ AddMethods(BaseSubobject(PrimaryBase, PrimaryBaseOffset),
+ PrimaryBaseOffsetInLayoutClass, FirstBaseInPrimaryBaseChain,
+ FirstBaseOffsetInLayoutClass, PrimaryBases);
if (!PrimaryBases.insert(PrimaryBase))
assert(false && "Found a duplicate primary base!");
@@ -1636,9 +1684,10 @@ VtableBuilder::AddMethods(BaseSubobject Base,
MethodInfoMap.insert(std::make_pair(MD, MethodInfo));
// Check if this overrider is going to be used.
- if (!IsOverriderUsed(Base, FirstBaseInPrimaryBaseChain, OffsetInLayoutClass,
- Overrider)) {
- const CXXMethodDecl *OverriderMD = Overrider.Method;
+ const CXXMethodDecl *OverriderMD = Overrider.Method;
+ if (!IsOverriderUsed(OverriderMD, BaseOffsetInLayoutClass,
+ FirstBaseInPrimaryBaseChain,
+ FirstBaseOffsetInLayoutClass)) {
Components.push_back(VtableComponent::MakeUnusedFunction(OverriderMD));
continue;
}
@@ -1662,7 +1711,8 @@ void VtableBuilder::LayoutVtable() {
VisitedVirtualBasesSetTy VBases;
// Determine the primary virtual bases.
- DeterminePrimaryVirtualBases(MostDerivedClass, VBases);
+ DeterminePrimaryVirtualBases(MostDerivedClass, MostDerivedClassOffset,
+ VBases);
VBases.clear();
LayoutVtablesForVirtualBases(MostDerivedClass, VBases);
@@ -1700,7 +1750,8 @@ VtableBuilder::LayoutPrimaryAndSecondaryVtables(BaseSubobject Base,
// Now go through all virtual member functions and add them.
PrimaryBasesSetVectorTy PrimaryBases;
- AddMethods(Base, Base, OffsetInLayoutClass, PrimaryBases);
+ AddMethods(Base, OffsetInLayoutClass, Base.getBase(), OffsetInLayoutClass,
+ PrimaryBases);
// Compute 'this' pointer adjustments.
ComputeThisAdjustments();
@@ -1771,7 +1822,8 @@ void VtableBuilder::LayoutSecondaryVtables(BaseSubobject Base,
}
void
-VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD,
+VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD,
+ uint64_t OffsetInLayoutClass,
VisitedVirtualBasesSetTy &VBases) {
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
@@ -1785,8 +1837,15 @@ VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD,
if (isBuildingConstructorVtable()) {
// Check if the base is actually a primary base in the class we use for
// layout.
- // FIXME: Is this check enough?
- if (MostDerivedClassOffset != 0)
+ const ASTRecordLayout &LayoutClassLayout =
+ Context.getASTRecordLayout(LayoutClass);
+
+ uint64_t PrimaryBaseOffsetInLayoutClass =
+ LayoutClassLayout.getVBaseClassOffset(PrimaryBase);
+
+ // We know that the base is not a primary base in the layout class if
+ // the base offsets are different.
+ if (PrimaryBaseOffsetInLayoutClass != OffsetInLayoutClass)
IsPrimaryVirtualBase = false;
}
@@ -1801,10 +1860,22 @@ VtableBuilder::DeterminePrimaryVirtualBases(const CXXRecordDecl *RD,
const CXXRecordDecl *BaseDecl =
cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
- if (I->isVirtual() && !VBases.insert(BaseDecl))
- continue;
+ uint64_t BaseOffsetInLayoutClass;
+
+ if (I->isVirtual()) {
+ if (!VBases.insert(BaseDecl))
+ continue;
+
+ const ASTRecordLayout &LayoutClassLayout =
+ Context.getASTRecordLayout(LayoutClass);
- DeterminePrimaryVirtualBases(BaseDecl, VBases);
+ BaseOffsetInLayoutClass = LayoutClassLayout.getVBaseClassOffset(BaseDecl);
+ } else {
+ BaseOffsetInLayoutClass =
+ OffsetInLayoutClass + Layout.getBaseClassOffset(BaseDecl);
+ }
+
+ DeterminePrimaryVirtualBases(BaseDecl, BaseOffsetInLayoutClass, VBases);
}
}
@@ -3405,7 +3476,22 @@ void CGVtableInfo::GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
Vtable = GenerateVtable(Linkage, /*GenerateDefinition=*/true, RD, RD, 0,
/*IsVirtual=*/false,
AddressPoints);
- GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD);
+ GenerateVTT(Linkage, /*GenerateDefinition=*/true, RD);
+
+ for (CXXRecordDecl::method_iterator i = RD->method_begin(),
+ e = RD->method_end(); i != e; ++i) {
+ if (!(*i)->isVirtual())
+ continue;
+ if(!(*i)->hasInlineBody() && !(*i)->isImplicit())
+ continue;
+
+ if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(*i)) {
+ CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Complete));
+ CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Deleting));
+ } else {
+ CGM.BuildThunksForVirtual(GlobalDecl(*i));
+ }
+ }
}
llvm::GlobalVariable *CGVtableInfo::getVtable(const CXXRecordDecl *RD) {
@@ -3438,19 +3524,12 @@ void CGVtableInfo::MaybeEmitVtable(GlobalDecl GD) {
return;
}
- // Emit the data.
- GenerateClassData(CGM.getVtableLinkage(RD), RD);
+ if (Vtables.count(RD))
+ return;
- for (CXXRecordDecl::method_iterator i = RD->method_begin(),
- e = RD->method_end(); i != e; ++i) {
- if ((*i)->isVirtual() && ((*i)->hasInlineBody() || (*i)->isImplicit())) {
- if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(*i)) {
- CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Complete));
- CGM.BuildThunksForVirtual(GlobalDecl(DD, Dtor_Deleting));
- } else {
- CGM.BuildThunksForVirtual(GlobalDecl(*i));
- }
- }
- }
+ TemplateSpecializationKind kind = RD->getTemplateSpecializationKind();
+ if (kind == TSK_ImplicitInstantiation)
+ CGM.DeferredVtables.push_back(RD);
+ else
+ GenerateClassData(CGM.getVtableLinkage(RD), RD);
}
-
diff --git a/lib/CodeGen/CGVtable.h b/lib/CodeGen/CGVtable.h
index 6ccb011..57220d9 100644
--- a/lib/CodeGen/CGVtable.h
+++ b/lib/CodeGen/CGVtable.h
@@ -173,15 +173,7 @@ private:
uint64_t getNumVirtualFunctionPointers(const CXXRecordDecl *RD);
void ComputeMethodVtableIndices(const CXXRecordDecl *RD);
-
- /// GenerateClassData - Generate all the class data requires to be generated
- /// upon definition of a KeyFunction. This includes the vtable, the
- /// rtti data structure and the VTT.
- ///
- /// \param Linkage - The desired linkage of the vtable, the RTTI and the VTT.
- void GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
- const CXXRecordDecl *RD);
-
+
llvm::GlobalVariable *
GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage,
bool GenerateDefinition, const CXXRecordDecl *LayoutClass,
@@ -245,6 +237,14 @@ public:
llvm::GlobalVariable *getVTT(const CXXRecordDecl *RD);
void MaybeEmitVtable(GlobalDecl GD);
+
+ /// GenerateClassData - Generate all the class data requires to be generated
+ /// upon definition of a KeyFunction. This includes the vtable, the
+ /// rtti data structure and the VTT.
+ ///
+ /// \param Linkage - The desired linkage of the vtable, the RTTI and the VTT.
+ void GenerateClassData(llvm::GlobalVariable::LinkageTypes Linkage,
+ const CXXRecordDecl *RD);
};
} // end namespace CodeGen
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index d6a56da..c67948d 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -488,7 +488,15 @@ void CodeGenModule::EmitDeferred() {
// Emit code for any potentially referenced deferred decls. Since a
// previously unused static decl may become used during the generation of code
// for a static function, iterate until no changes are made.
- while (!DeferredDeclsToEmit.empty()) {
+
+ while (!DeferredDeclsToEmit.empty() || !DeferredVtables.empty()) {
+ if (!DeferredVtables.empty()) {
+ const CXXRecordDecl *RD = DeferredVtables.back();
+ DeferredVtables.pop_back();
+ getVtableInfo().GenerateClassData(getVtableLinkage(RD), RD);
+ continue;
+ }
+
GlobalDecl D = DeferredDeclsToEmit.back();
DeferredDeclsToEmit.pop_back();
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index c86f8b4..40dc563 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -451,7 +451,9 @@ public:
/// GetTargetTypeStoreSize - Return the store size, in character units, of
/// the given LLVM type.
CharUnits GetTargetTypeStoreSize(const llvm::Type *Ty) const;
-
+
+ std::vector<const CXXRecordDecl*> DeferredVtables;
+
private:
/// UniqueMangledName - Unique a name by (if necessary) inserting it into the
/// MangledNames string map.
diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp
index 20d54b3..2e0580f 100644
--- a/lib/CodeGen/Mangle.cpp
+++ b/lib/CodeGen/Mangle.cpp
@@ -214,12 +214,6 @@ bool MangleContext::shouldMangleDeclName(const NamedDecl *D) {
if (!getASTContext().getLangOptions().CPlusPlus)
return false;
- // No mangling in an "implicit extern C" header.
- if (D->getLocation().isValid() &&
- getASTContext().getSourceManager().
- isInExternCSystemHeader(D->getLocation()))
- return false;
-
// Variables at global scope with non-internal linkage are not mangled
if (!FD) {
const DeclContext *DC = D->getDeclContext();
diff --git a/lib/Driver/HostInfo.cpp b/lib/Driver/HostInfo.cpp
index 98b64f1..d8e086d 100644
--- a/lib/Driver/HostInfo.cpp
+++ b/lib/Driver/HostInfo.cpp
@@ -164,7 +164,7 @@ class TCEHostInfo : public HostInfo {
public:
TCEHostInfo(const Driver &D, const llvm::Triple &Triple);
- ~TCEHostInfo() {};
+ ~TCEHostInfo() {}
virtual bool useDriverDriver() const;
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index de9bdcc..bc52100 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -929,7 +929,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Special case debug options to only pass -g to clang. This is
// wrong.
- if (Args.hasArg(options::OPT_g_Group))
+ Args.ClaimAllArgs(options::OPT_g_Group);
+ Arg *Garg = Args.getLastArg(options::OPT_g_Group);
+ if (Garg && Garg != Args.getLastArg(options::OPT_g0))
CmdArgs.push_back("-g");
Args.AddLastArg(CmdArgs, options::OPT_nostdinc);
diff --git a/lib/Frontend/CacheTokens.cpp b/lib/Frontend/CacheTokens.cpp
index 702c1d0..c845d56 100644
--- a/lib/Frontend/CacheTokens.cpp
+++ b/lib/Frontend/CacheTokens.cpp
@@ -64,7 +64,7 @@ public:
PTHEntryKeyVariant(struct stat* statbuf, const char* path)
: Path(path), Kind(IsDE), StatBuf(new struct stat(*statbuf)) {}
- PTHEntryKeyVariant(const char* path)
+ explicit PTHEntryKeyVariant(const char* path)
: Path(path), Kind(IsNoExist), StatBuf(0) {}
bool isFile() const { return Kind == IsFE; }
@@ -513,7 +513,7 @@ public:
int result = StatSysCallCache::stat(path, buf);
if (result != 0) // Failed 'stat'.
- PM.insert(path, PTHEntry());
+ PM.insert(PTHEntryKeyVariant(path), PTHEntry());
else if (S_ISDIR(buf->st_mode)) {
// Only cache directories with absolute paths.
if (!llvm::sys::Path(path).isAbsolute())
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index 1831ca5..25b804a 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -94,7 +94,7 @@ namespace {
public:
explicit BinaryDiagnosticSerializer(llvm::raw_ostream &OS)
: OS(OS), SourceMgr(0) { }
-
+
virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
const DiagnosticInfo &Info);
};
@@ -341,7 +341,7 @@ void CompilerInstance::addOutputFile(llvm::StringRef Path,
OutputFiles.push_back(std::make_pair(Path, OS));
}
-void CompilerInstance::ClearOutputFiles(bool EraseFiles) {
+void CompilerInstance::clearOutputFiles(bool EraseFiles) {
for (std::list< std::pair<std::string, llvm::raw_ostream*> >::iterator
it = OutputFiles.begin(), ie = OutputFiles.end(); it != ie; ++it) {
delete it->second;
diff --git a/lib/Frontend/DeclXML.cpp b/lib/Frontend/DeclXML.cpp
index d7470d9..8750b1e 100644
--- a/lib/Frontend/DeclXML.cpp
+++ b/lib/Frontend/DeclXML.cpp
@@ -29,6 +29,14 @@ class DocumentXML::DeclPrinter : public DeclVisitor<DocumentXML::DeclPrinter> {
}
}
+ void addFunctionBody(FunctionDecl* FD) {
+ if (FD->isThisDeclarationADefinition()) {
+ Doc.addSubNode("Body");
+ Doc.PrintStmt(FD->getBody());
+ Doc.toParent();
+ }
+ }
+
void addSubNodes(RecordDecl* RD) {
for (RecordDecl::field_iterator i = RD->field_begin(),
e = RD->field_end(); i != e; ++i) {
@@ -37,6 +45,15 @@ class DocumentXML::DeclPrinter : public DeclVisitor<DocumentXML::DeclPrinter> {
}
}
+ void addSubNodes(CXXRecordDecl* RD) {
+ addSubNodes(cast<RecordDecl>(RD));
+ for (CXXRecordDecl::method_iterator i = RD->method_begin(),
+ e = RD->method_end(); i != e; ++i) {
+ Visit(*i);
+ Doc.toParent();
+ }
+ }
+
void addSubNodes(EnumDecl* ED) {
for (EnumDecl::enumerator_iterator i = ED->enumerator_begin(),
e = ED->enumerator_end(); i != e; ++i) {
@@ -115,6 +132,8 @@ public:
#define SUB_NODE_SEQUENCE_XML( CLASS ) addSubNodes(T);
#define SUB_NODE_OPT_XML( CLASS ) addSubNodes(T);
+#define SUB_NODE_FN_BODY_XML addFunctionBody(T);
+
#include "clang/Frontend/DeclXML.def"
};
@@ -122,13 +141,6 @@ public:
//---------------------------------------------------------
void DocumentXML::writeDeclToXML(Decl *D) {
DeclPrinter(*this).Visit(D);
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- if (Stmt *Body = FD->getBody()) {
- addSubNode("Body");
- PrintStmt(Body);
- toParent();
- }
- }
toParent();
}
diff --git a/lib/Frontend/DependencyFile.cpp b/lib/Frontend/DependencyFile.cpp
index 478c339..de2b056 100644
--- a/lib/Frontend/DependencyFile.cpp
+++ b/lib/Frontend/DependencyFile.cpp
@@ -74,8 +74,7 @@ void clang::AttachDependencyFileGen(Preprocessor &PP,
return;
}
- assert(!PP.getPPCallbacks() && "Preprocessor callbacks already registered!");
- PP.setPPCallbacks(new DependencyFileCallback(&PP, OS, Opts));
+ PP.addPPCallbacks(new DependencyFileCallback(&PP, OS, Opts));
}
/// FileMatchesDepCriteria - Determine whether the given Filename should be
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index 96a68c9..66df7a6 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -180,7 +180,7 @@ void FrontendAction::EndSourceFile() {
// Cleanup the output streams, and erase the output files if we encountered
// an error.
- CI.ClearOutputFiles(/*EraseFiles=*/CI.getDiagnostics().getNumErrors());
+ CI.clearOutputFiles(/*EraseFiles=*/CI.getDiagnostics().getNumErrors());
// Inform the diagnostic client we are done with this source file.
CI.getDiagnosticClient().EndSourceFile();
diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp
index 4f972f0..cd749d2 100644
--- a/lib/Frontend/InitHeaderSearch.cpp
+++ b/lib/Frontend/InitHeaderSearch.cpp
@@ -436,7 +436,7 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple) {
break;
}
- AddPath("/usr/local/include", System, false, false, false);
+ AddPath("/usr/local/include", System, true, false, false);
AddPath("/usr/include", System, false, false, false);
}
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index a878df7..267f4c1 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -120,7 +120,7 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) {
PARSE_LANGOPT_IMPORTANT(OpenCL, diag::warn_pch_opencl);
PARSE_LANGOPT_BENIGN(CatchUndefined);
PARSE_LANGOPT_IMPORTANT(ElideConstructors, diag::warn_pch_elide_constructors);
-#undef PARSE_LANGOPT_IRRELEVANT
+#undef PARSE_LANGOPT_IMPORTANT
#undef PARSE_LANGOPT_BENIGN
return false;
@@ -1089,13 +1089,13 @@ void PCHReader::ReadDefinedMacros() {
// If there was no preprocessor block, do nothing.
if (!MacroCursor.getBitStreamReader())
return;
-
+
llvm::BitstreamCursor Cursor = MacroCursor;
if (Cursor.EnterSubBlock(pch::PREPROCESSOR_BLOCK_ID)) {
Error("malformed preprocessor block record in PCH file");
return;
}
-
+
RecordData Record;
while (true) {
unsigned Code = Cursor.ReadCode();
@@ -1104,7 +1104,7 @@ void PCHReader::ReadDefinedMacros() {
Error("error at end of preprocessor block in PCH file");
return;
}
-
+
if (Code == llvm::bitc::ENTER_SUBBLOCK) {
// No known subblocks, always skip them.
Cursor.ReadSubBlockID();
@@ -1114,12 +1114,12 @@ void PCHReader::ReadDefinedMacros() {
}
continue;
}
-
+
if (Code == llvm::bitc::DEFINE_ABBREV) {
Cursor.ReadAbbrevRecord();
continue;
}
-
+
// Read a record.
const char *BlobStart;
unsigned BlobLen;
@@ -1127,7 +1127,7 @@ void PCHReader::ReadDefinedMacros() {
switch (Cursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
default: // Default behavior: ignore.
break;
-
+
case pch::PP_MACRO_OBJECT_LIKE:
case pch::PP_MACRO_FUNCTION_LIKE:
DecodeIdentifierInfo(Record[0]);
@@ -1339,7 +1339,7 @@ PCHReader::ReadPCHBlock() {
}
UnusedStaticFuncs.swap(Record);
break;
-
+
case pch::LOCALLY_SCOPED_EXTERNAL_DECLS:
if (!LocallyScopedExternalDecls.empty()) {
Error("duplicate LOCALLY_SCOPED_EXTERNAL_DECLS record in PCH file");
@@ -1385,7 +1385,7 @@ PCHReader::ReadPCHBlock() {
break;
case pch::STAT_CACHE: {
- PCHStatCache *MyStatCache =
+ PCHStatCache *MyStatCache =
new PCHStatCache((const unsigned char *)BlobStart + Record[0],
(const unsigned char *)BlobStart,
NumStatHits, NumStatMisses);
@@ -1393,7 +1393,7 @@ PCHReader::ReadPCHBlock() {
StatCache = MyStatCache;
break;
}
-
+
case pch::EXT_VECTOR_DECLS:
if (!ExtVectorDecls.empty()) {
Error("duplicate EXT_VECTOR_DECLS record in PCH file");
@@ -1412,7 +1412,7 @@ PCHReader::ReadPCHBlock() {
Comments = (SourceRange *)BlobStart;
NumComments = BlobLen / sizeof(SourceRange);
break;
-
+
case pch::VERSION_CONTROL_BRANCH_REVISION: {
const std::string &CurBranch = getClangFullRepositoryVersion();
llvm::StringRef PCHBranch(BlobStart, BlobLen);
@@ -1561,7 +1561,7 @@ void PCHReader::InitializeContext(ASTContext &Ctx) {
PP->getIdentifierTable().setExternalIdentifierLookup(this);
PP->getHeaderSearchInfo().SetExternalLookup(this);
PP->setExternalSource(this);
-
+
// Load the translation unit declaration
ReadDeclRecord(DeclOffsets[0], 0);
@@ -2018,6 +2018,12 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
Context->getSubstTemplateTypeParmType(cast<TemplateTypeParmType>(Parm),
Replacement);
}
+
+ case pch::TYPE_INJECTED_CLASS_NAME: {
+ CXXRecordDecl *D = cast<CXXRecordDecl>(GetDecl(Record[0]));
+ QualType TST = GetType(Record[1]); // probably derivable
+ return Context->getInjectedClassNameType(D, TST);
+ }
}
// Suppress a GCC warning
return QualType();
@@ -2172,6 +2178,9 @@ void TypeLocReader::VisitTemplateSpecializationTypeLoc(
void TypeLocReader::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) {
TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
}
+void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
+ TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+}
void TypeLocReader::VisitTypenameTypeLoc(TypenameTypeLoc TL) {
TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
}
@@ -2271,7 +2280,7 @@ PCHReader::GetTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
case TemplateArgument::Type:
return GetTypeSourceInfo(Record, Index);
case TemplateArgument::Template: {
- SourceLocation
+ SourceLocation
QualStart = SourceLocation::getFromRawEncoding(Record[Index++]),
QualEnd = SourceLocation::getFromRawEncoding(Record[Index++]),
TemplateNameLoc = SourceLocation::getFromRawEncoding(Record[Index++]);
@@ -2487,7 +2496,7 @@ void PCHReader::InitializeSema(Sema &S) {
VarDecl *Var = cast<VarDecl>(GetDecl(TentativeDefinitions[I]));
SemaObj->TentativeDefinitions.push_back(Var);
}
-
+
// If there were any unused static functions, deserialize them and add to
// Sema's list of unused static functions.
for (unsigned I = 0, N = UnusedStaticFuncs.size(); I != N; ++I) {
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp
index 356bd07..a3f5eac 100644
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -211,6 +211,7 @@ void PCHDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
MD->setDeclImplementation((ObjCMethodDecl::ImplementationControl)Record[Idx++]);
MD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
MD->setResultType(Reader.GetType(Record[Idx++]));
+ MD->setResultTypeSourceInfo(Reader.GetTypeSourceInfo(Record, Idx));
MD->setEndLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
unsigned NumParams = Record[Idx++];
llvm::SmallVector<ParmVarDecl *, 16> Params;
@@ -690,7 +691,7 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
break;
case pch::DECL_OBJC_METHOD:
D = ObjCMethodDecl::Create(*Context, SourceLocation(), SourceLocation(),
- Selector(), QualType(), 0);
+ Selector(), QualType(), 0, 0);
break;
case pch::DECL_OBJC_INTERFACE:
D = ObjCInterfaceDecl::Create(*Context, 0, SourceLocation(), 0);
diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp
index d123694..7b94805 100644
--- a/lib/Frontend/PCHReaderStmt.cpp
+++ b/lib/Frontend/PCHReaderStmt.cpp
@@ -792,8 +792,9 @@ unsigned PCHStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) {
cast_or_null<Expr>(StmtStack[StmtStack.size() - E->getNumArgs() - 1]));
if (!E->getReceiver()) {
ObjCMessageExpr::ClassInfo CI;
- CI.first = cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++]));
- CI.second = Reader.GetIdentifierInfo(Record, Idx);
+ CI.Decl = cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++]));
+ CI.Name = Reader.GetIdentifierInfo(Record, Idx);
+ CI.Loc = SourceLocation::getFromRawEncoding(Record[Idx++]);
E->setClassInfo(CI);
}
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 93af754..eed3cc1 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -235,6 +235,12 @@ void PCHTypeWriter::VisitQualifiedNameType(const QualifiedNameType *T) {
assert(false && "Cannot serialize qualified name types");
}
+void PCHTypeWriter::VisitInjectedClassNameType(const InjectedClassNameType *T) {
+ Writer.AddDeclRef(T->getDecl(), Record);
+ Writer.AddTypeRef(T->getUnderlyingType(), Record);
+ Code = pch::TYPE_INJECTED_CLASS_NAME;
+}
+
void PCHTypeWriter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
Writer.AddDeclRef(T->getDecl(), Record);
Record.push_back(T->getNumProtocols());
@@ -394,6 +400,9 @@ void TypeLocWriter::VisitTemplateSpecializationTypeLoc(
void TypeLocWriter::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) {
Writer.AddSourceLocation(TL.getNameLoc(), Record);
}
+void TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
+ Writer.AddSourceLocation(TL.getNameLoc(), Record);
+}
void TypeLocWriter::VisitTypenameTypeLoc(TypenameTypeLoc TL) {
Writer.AddSourceLocation(TL.getNameLoc(), Record);
}
diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp
index e776d32..0774797 100644
--- a/lib/Frontend/PCHWriterDecl.cpp
+++ b/lib/Frontend/PCHWriterDecl.cpp
@@ -210,6 +210,7 @@ void PCHDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
// FIXME: stable encoding for in/out/inout/bycopy/byref/oneway
Record.push_back(D->getObjCDeclQualifier());
Writer.AddTypeRef(D->getResultType(), Record);
+ Writer.AddTypeSourceInfo(D->getResultTypeSourceInfo(), Record);
Writer.AddSourceLocation(D->getLocEnd(), Record);
Record.push_back(D->param_size());
for (ObjCMethodDecl::param_iterator P = D->param_begin(),
diff --git a/lib/Frontend/PCHWriterStmt.cpp b/lib/Frontend/PCHWriterStmt.cpp
index a8cc9d6..9a5417c 100644
--- a/lib/Frontend/PCHWriterStmt.cpp
+++ b/lib/Frontend/PCHWriterStmt.cpp
@@ -720,8 +720,9 @@ void PCHStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
if (!E->getReceiver()) {
ObjCMessageExpr::ClassInfo CI = E->getClassInfo();
- Writer.AddDeclRef(CI.first, Record);
- Writer.AddIdentifierRef(CI.second, Record);
+ Writer.AddDeclRef(CI.Decl, Record);
+ Writer.AddIdentifierRef(CI.Name, Record);
+ Writer.AddSourceLocation(CI.Loc, Record);
}
for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp
index 774372c..be5bb0d 100644
--- a/lib/Frontend/PrintPreprocessedOutput.cpp
+++ b/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -52,7 +52,7 @@ static void PrintMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI,
if (MI.isGNUVarargs())
OS << "..."; // #define foo(x...)
-
+
OS << ')';
}
@@ -102,7 +102,7 @@ public:
EmittedMacroOnThisLine = false;
FileType = SrcMgr::C_User;
Initialized = false;
-
+
// If we're in microsoft mode, use normal #line instead of line markers.
UseLineDirective = PP.getLangOptions().Microsoft;
}
@@ -150,7 +150,7 @@ void PrintPPOutputPPCallbacks::WriteLineInfo(unsigned LineNo,
OS << '#' << ' ' << LineNo << ' ' << '"';
OS.write(&CurFilename[0], CurFilename.size());
OS << '"';
-
+
if (ExtraLen)
OS.write(Extra, ExtraLen);
@@ -492,7 +492,7 @@ void clang::DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream *OS,
PP.AddPragmaHandler("GCC", new UnknownPragmaHandler("#pragma GCC",
Callbacks));
- PP.setPPCallbacks(Callbacks);
+ PP.addPPCallbacks(Callbacks);
// After we have configured the preprocessor, enter the main file.
PP.EnterMainSourceFile();
diff --git a/lib/Headers/smmintrin.h b/lib/Headers/smmintrin.h
index d91ed1d..b3bdac6 100644
--- a/lib/Headers/smmintrin.h
+++ b/lib/Headers/smmintrin.h
@@ -32,6 +32,7 @@
/* Type defines. */
typedef double __v2df __attribute__ ((__vector_size__ (16)));
+typedef long long __v2di __attribute__ ((__vector_size__ (16)));
/* SSE4 Rounding macros. */
#define _MM_FROUND_TO_NEAREST_INT 0x00
@@ -48,7 +49,7 @@ typedef double __v2df __attribute__ ((__vector_size__ (16)));
#define _MM_FROUND_CEIL (_MM_FROUND_RAISE_EXC | _MM_FROUND_TO_POS_INF)
#define _MM_FROUND_TRUNC (_MM_FROUND_RAISE_EXC | _MM_FROUND_TO_ZERO)
#define _MM_FROUND_RINT (_MM_FROUND_RAISE_EXC | _MM_FROUND_CUR_DIRECTION)
-#define _MM_FROUND_NEARBYINT (_MM_FROUND_RAISE_EXC | _MM_FROUND_CUR_DIRECTION)
+#define _MM_FROUND_NEARBYINT (_MM_FROUND_NO_EXC | _MM_FROUND_CUR_DIRECTION)
#define _mm_ceil_ps(X) _mm_round_ps((X), _MM_FROUND_CEIL)
#define _mm_ceil_pd(X) _mm_round_pd((X), _MM_FROUND_CEIL)
@@ -60,30 +61,10 @@ typedef double __v2df __attribute__ ((__vector_size__ (16)));
#define _mm_floor_ss(X, Y) _mm_round_ss((X), (Y), _MM_FROUND_FLOOR)
#define _mm_floor_sd(X, Y) _mm_round_sd((X), (Y), _MM_FROUND_FLOOR)
-/* SSE4 Rounding Intrinsics. */
-static inline __m128 __attribute__((__always_inline__, __nodebug__))
-_mm_round_ps (__m128 __V, const int __M)
-{
- return (__m128) __builtin_ia32_roundps ((__v4sf)__V, __M);
-}
-
-static inline __m128 __attribute__((__always_inline__, __nodebug__))
-_mm_round_ss (__m128 __V1, __m128 __V2, const int __M)
-{
- return (__m128) __builtin_ia32_roundss ((__v4sf)__V1, (__v4sf)__V2, __M);
-}
-
-static inline __m128d __attribute__((__always_inline__, __nodebug__))
-_mm_round_pd (__m128d __V, const int __M)
-{
- return (__m128d) __builtin_ia32_roundpd ((__v2df)__V, __M);
-}
-
-static inline __m128d __attribute__((__always_inline__, __nodebug__))
-_mm_round_sd(__m128d __V1, __m128d __V2, const int __M)
-{
- return (__m128d) __builtin_ia32_roundsd ((__v2df)__V1, (__v2df)__V2, __M);
-}
+#define _mm_round_ps(X, Y) __builtin_ia32_roundps((X), (Y))
+#define _mm_round_ss(X, Y, M) __builtin_ia32_roundss((X), (Y), (M))
+#define _mm_round_pd(X, M) __builtin_ia32_roundpd((X), (M))
+#define _mm_round_sd(X, Y, M) __builtin_ia32_roundsd((X), (Y), (M))
/* SSE4 Packed Blending Intrinsics. */
static inline __m128d __attribute__((__always_inline__, __nodebug__))
@@ -125,6 +106,100 @@ _mm_blend_epi16 (__m128i __V1, __m128i __V2, const int __M)
return (__m128i) __builtin_ia32_pblendw128 ((__v8hi)__V1, (__v8hi)__V2, __M);
}
+/* SSE4 Dword Multiply Instructions. */
+static inline __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_mullo_epi32 (__m128i __V1, __m128i __V2)
+{
+ return (__m128i) __builtin_ia32_pmulld128((__v4si)__V1, (__v4si)__V2);
+}
+
+static inline __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_mul_epi32 (__m128i __V1, __m128i __V2)
+{
+ return (__m128i) __builtin_ia32_pmuldq128 ((__v4si)__V1, (__v4si)__V2);
+}
+
+/* SSE4 Floating Point Dot Product Instructions. */
+#define _mm_dp_ps(X, Y, M) __builtin_ia32_dpps ((X), (Y), (M))
+#define _mm_dp_pd(X, Y, M) __builtin_ia32_dppd ((X), (Y), (M))
+
+/* SSE4 Streaming Load Hint Instruction. */
+static inline __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_stream_load_si128 (__m128i *__V)
+{
+ return (__m128i) __builtin_ia32_movntdqa ((__v2di *) __V);
+}
+
+/* SSE4 Packed Integer Min/Max Instructions. */
+static inline __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_min_epi8 (__m128i __V1, __m128i __V2)
+{
+ return (__m128i) __builtin_ia32_pminsb128 ((__v16qi) __V1, (__v16qi) __V2);
+}
+
+static inline __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_max_epi8 (__m128i __V1, __m128i __V2)
+{
+ return (__m128i) __builtin_ia32_pmaxsb128 ((__v16qi) __V1, (__v16qi) __V2);
+}
+
+static inline __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_min_epu16 (__m128i __V1, __m128i __V2)
+{
+ return (__m128i) __builtin_ia32_pminuw128 ((__v8hi) __V1, (__v8hi) __V2);
+}
+
+static inline __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_max_epu16 (__m128i __V1, __m128i __V2)
+{
+ return (__m128i) __builtin_ia32_pmaxuw128 ((__v8hi) __V1, (__v8hi) __V2);
+}
+
+static inline __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_min_epi32 (__m128i __V1, __m128i __V2)
+{
+ return (__m128i) __builtin_ia32_pminsd128 ((__v4si) __V1, (__v4si) __V2);
+}
+
+static inline __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_max_epi32 (__m128i __V1, __m128i __V2)
+{
+ return (__m128i) __builtin_ia32_pmaxsd128 ((__v4si) __V1, (__v4si) __V2);
+}
+
+static inline __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_min_epu32 (__m128i __V1, __m128i __V2)
+{
+ return (__m128i) __builtin_ia32_pminud128((__v4si) __V1, (__v4si) __V2);
+}
+
+static inline __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_max_epu32 (__m128i __V1, __m128i __V2)
+{
+ return (__m128i) __builtin_ia32_pmaxud128((__v4si) __V1, (__v4si) __V2);
+}
+
+/* SSE4 Insertion and Extraction from XMM Register Instructions. */
+#define _mm_insert_ps(X, Y, N) __builtin_ia32_insertps128((X), (Y), (N))
+#define _mm_extract_ps(X, N) (__extension__ \
+ ({ union { int i; float f; } __t; \
+ __v4sf __a = (__v4sf)X; \
+ __t.f = __a[N]; \
+ __t.i;}))
+
+/* Miscellaneous insert and extract macros. */
+/* Extract a single-precision float from X at index N into D. */
+#define _MM_EXTRACT_FLOAT(D, X, N) (__extension__ ({ __v4sf __a = (__v4sf)X; \
+ (D) = __a[N]; }))
+
+/* Or together 2 sets of indexes (X and Y) with the zeroing bits (Z) to create
+ an index suitable for _mm_insert_ps. */
+#define _MM_MK_INSERTPS_NDX(X, Y, Z) (((X) << 6) | ((Y) << 4) | (Z))
+
+/* Extract a float from X at index N into the first index of the return. */
+#define _MM_PICK_OUT_PS(X, N) _mm_insert_ps (_mm_setzero_ps(), (X), \
+ _MM_MK_INSERTPS_NDX((N), 0, 0x0e))
+
#endif /* __SSE4_1__ */
#endif /* _SMMINTRIN_H */
diff --git a/lib/Headers/stdarg.h b/lib/Headers/stdarg.h
index bbbaff9..c36ab12 100644
--- a/lib/Headers/stdarg.h
+++ b/lib/Headers/stdarg.h
@@ -26,7 +26,10 @@
#ifndef __STDARG_H
#define __STDARG_H
+#ifndef _VA_LIST
typedef __builtin_va_list va_list;
+#define _VA_LIST
+#endif
#define va_start(ap, param) __builtin_va_start(ap, param)
#define va_end(ap) __builtin_va_end(ap)
#define va_arg(ap, type) __builtin_va_arg(ap, type)
diff --git a/lib/Headers/stddef.h b/lib/Headers/stddef.h
index 2c84b4b..6868ad3 100644
--- a/lib/Headers/stddef.h
+++ b/lib/Headers/stddef.h
@@ -27,11 +27,18 @@
#define __STDDEF_H
typedef __typeof__(((int*)0)-((int*)0)) ptrdiff_t;
+#ifndef _SIZE_T
+#define _SIZE_T
typedef __typeof__(sizeof(int)) size_t;
+#endif
#ifndef __cplusplus
+#ifndef _WCHAR_T
+#define _WCHAR_T
typedef __typeof__(*L"") wchar_t;
#endif
+#endif
+#undef NULL
#ifdef __cplusplus
#define NULL __null
#else
diff --git a/lib/Index/Analyzer.cpp b/lib/Index/Analyzer.cpp
index fb3529d..7b414f2 100644
--- a/lib/Index/Analyzer.cpp
+++ b/lib/Index/Analyzer.cpp
@@ -177,7 +177,7 @@ public:
if (IsInstanceMethod)
return false;
- MsgD = Msg->getClassInfo().first;
+ MsgD = Msg->getClassInfo().Decl;
// FIXME: Case when we only have an identifier.
assert(MsgD && "Identifier only");
}
@@ -250,7 +250,7 @@ public:
while (true) {
if (Msg->getReceiver() == 0) {
CanBeClassMethod = true;
- MsgD = Msg->getClassInfo().first;
+ MsgD = Msg->getClassInfo().Decl;
// FIXME: Case when we only have an identifier.
assert(MsgD && "Identifier only");
break;
diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp
index 8c4caaf..299e84e 100644
--- a/lib/Sema/CodeCompleteConsumer.cpp
+++ b/lib/Sema/CodeCompleteConsumer.cpp
@@ -17,7 +17,6 @@
#include "clang-c/Index.h"
#include "Sema.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstring>
diff --git a/lib/Sema/JumpDiagnostics.cpp b/lib/Sema/JumpDiagnostics.cpp
index 7cf207f..1c761b9 100644
--- a/lib/Sema/JumpDiagnostics.cpp
+++ b/lib/Sema/JumpDiagnostics.cpp
@@ -85,6 +85,8 @@ static unsigned GetDiagForGotoScopeDecl(const Decl *D, bool isCPlusPlus) {
return diag::note_protected_by_cleanup;
if (VD->hasAttr<BlocksAttr>())
return diag::note_protected_by___block;
+ // FIXME: In C++0x, we have to check more conditions than "did we
+ // just give it an initializer?". See 6.7p3.
if (isCPlusPlus && VD->hasLocalStorage() && VD->hasInit())
return diag::note_protected_by_variable_init;
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp
index 0097cd3..e04abd2 100644
--- a/lib/Sema/SemaCXXCast.cpp
+++ b/lib/Sema/SemaCXXCast.cpp
@@ -84,7 +84,8 @@ static TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType,
QualType OrigSrcType,
QualType OrigDestType, unsigned &msg,
CastExpr::CastKind &Kind);
-static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, QualType SrcType,
+static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr,
+ QualType SrcType,
QualType DestType,bool CStyle,
const SourceRange &OpRange,
unsigned &msg,
@@ -554,7 +555,7 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
// Reverse member pointer conversion. C++ 4.11 specifies member pointer
// conversion. C++ 5.2.9p9 has additional information.
// DR54's access restrictions apply here also.
- tcr = TryStaticMemberPointerUpcast(Self, SrcType, DestType, CStyle,
+ tcr = TryStaticMemberPointerUpcast(Self, SrcExpr, SrcType, DestType, CStyle,
OpRange, msg, Kind);
if (tcr != TC_NotApplicable)
return tcr;
@@ -798,12 +799,23 @@ TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType,
/// where B is a base class of D [...].
///
TryCastResult
-TryStaticMemberPointerUpcast(Sema &Self, QualType SrcType, QualType DestType,
- bool CStyle, const SourceRange &OpRange,
+TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType,
+ QualType DestType, bool CStyle,
+ const SourceRange &OpRange,
unsigned &msg, CastExpr::CastKind &Kind) {
const MemberPointerType *DestMemPtr = DestType->getAs<MemberPointerType>();
if (!DestMemPtr)
return TC_NotApplicable;
+
+ bool WasOverloadedFunction = false;
+ if (FunctionDecl *Fn
+ = Self.ResolveAddressOfOverloadedFunction(SrcExpr, DestType, false)) {
+ CXXMethodDecl *M = cast<CXXMethodDecl>(Fn);
+ SrcType = Self.Context.getMemberPointerType(Fn->getType(),
+ Self.Context.getTypeDeclType(M->getParent()).getTypePtr());
+ WasOverloadedFunction = true;
+ }
+
const MemberPointerType *SrcMemPtr = SrcType->getAs<MemberPointerType>();
if (!SrcMemPtr) {
msg = diag::err_bad_static_cast_member_pointer_nonmp;
@@ -853,6 +865,24 @@ TryStaticMemberPointerUpcast(Sema &Self, QualType SrcType, QualType DestType,
return TC_Failed;
}
+ if (WasOverloadedFunction) {
+ // Resolve the address of the overloaded function again, this time
+ // allowing complaints if something goes wrong.
+ FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(SrcExpr,
+ DestType,
+ true);
+ if (!Fn) {
+ msg = 0;
+ return TC_Failed;
+ }
+
+ SrcExpr = Self.FixOverloadedFunctionReference(SrcExpr, Fn);
+ if (!SrcExpr) {
+ msg = 0;
+ return TC_Failed;
+ }
+ }
+
Kind = CastExpr::CK_DerivedToBaseMemberPointer;
return TC_Success;
}
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index 971b78c..95b79ab 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -76,14 +76,6 @@ getCurrentInstantiationOf(ASTContext &Context, DeclContext *CurContext,
// our context.
if (Context.getCanonicalType(Context.getTypeDeclType(Record)) == T)
return Record;
-
- if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate()) {
- QualType InjectedClassName
- = Template->getInjectedClassNameType(Context);
- if (T == Context.getCanonicalType(InjectedClassName))
- return Template->getTemplatedDecl();
- }
- // FIXME: check for class template partial specializations
}
return 0;
@@ -130,8 +122,11 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS,
return Record;
if (EnteringContext) {
- if (const TemplateSpecializationType *SpecType
- = dyn_cast_or_null<TemplateSpecializationType>(NNS->getAsType())) {
+ const Type *NNSType = NNS->getAsType();
+ if (!NNSType) {
+ // do nothing, fall out
+ } else if (const TemplateSpecializationType *SpecType
+ = NNSType->getAs<TemplateSpecializationType>()) {
// We are entering the context of the nested name specifier, so try to
// match the nested name specifier to either a primary class template
// or a class template partial specialization.
@@ -144,7 +139,8 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS,
// If the type of the nested name specifier is the same as the
// injected class name of the named class template, we're entering
// into that class template definition.
- QualType Injected = ClassTemplate->getInjectedClassNameType(Context);
+ QualType Injected
+ = ClassTemplate->getInjectedClassNameSpecialization(Context);
if (Context.hasSameType(Injected, ContextType))
return ClassTemplate->getTemplatedDecl();
@@ -156,8 +152,7 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS,
= ClassTemplate->findPartialSpecialization(ContextType))
return PartialSpec;
}
- } else if (const RecordType *RecordT
- = dyn_cast_or_null<RecordType>(NNS->getAsType())) {
+ } else if (const RecordType *RecordT = NNSType->getAs<RecordType>()) {
// The nested name specifier refers to a member of a class template.
return RecordT->getDecl();
}
@@ -248,7 +243,7 @@ bool Sema::RequireCompleteDeclContext(const CXXScopeSpec &SS) {
// If we're currently defining this type, then lookup into the
// type is okay: don't complain that it isn't complete yet.
const TagType *TagT = Context.getTypeDeclType(Tag)->getAs<TagType>();
- if (TagT->isBeingDefined())
+ if (TagT && TagT->isBeingDefined())
return false;
// The type must be complete.
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index ec1939e..94fcfc6 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -188,18 +188,6 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
if (TypeDecl *TD = dyn_cast<TypeDecl>(IIDecl)) {
DiagnoseUseOfDecl(IIDecl, NameLoc);
- // C++ [temp.local]p2:
- // Within the scope of a class template specialization or
- // partial specialization, when the injected-class-name is
- // not followed by a <, it is equivalent to the
- // injected-class-name followed by the template-argument s
- // of the class template specialization or partial
- // specialization enclosed in <>.
- if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(TD))
- if (RD->isInjectedClassName())
- if (ClassTemplateDecl *Template = RD->getDescribedClassTemplate())
- T = Template->getInjectedClassNameType(Context);
-
if (T.isNull())
T = Context.getTypeDeclType(TD);
@@ -1773,12 +1761,7 @@ DeclarationName Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
return DeclarationName();
// Determine the type of the class being constructed.
- QualType CurClassType;
- if (ClassTemplateDecl *ClassTemplate
- = CurClass->getDescribedClassTemplate())
- CurClassType = ClassTemplate->getInjectedClassNameType(Context);
- else
- CurClassType = Context.getTypeDeclType(CurClass);
+ QualType CurClassType = Context.getTypeDeclType(CurClass);
// FIXME: Check two things: that the template-id names the same type as
// CurClassType, and that the template-id does not occur when the name
@@ -3809,24 +3792,38 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl,
return;
}
- InitializedEntity Entity = InitializedEntity::InitializeVariable(Var);
- InitializationKind Kind
- = InitializationKind::CreateDefault(Var->getLocation());
+ const RecordType *Record
+ = Context.getBaseElementType(Type)->getAs<RecordType>();
+ if (Record && getLangOptions().CPlusPlus && !getLangOptions().CPlusPlus0x &&
+ cast<CXXRecordDecl>(Record->getDecl())->isPOD()) {
+ // C++03 [dcl.init]p9:
+ // If no initializer is specified for an object, and the
+ // object is of (possibly cv-qualified) non-POD class type (or
+ // array thereof), the object shall be default-initialized; if
+ // the object is of const-qualified type, the underlying class
+ // type shall have a user-declared default
+ // constructor. Otherwise, if no initializer is specified for
+ // a non- static object, the object and its subobjects, if
+ // any, have an indeterminate initial value); if the object
+ // or any of its subobjects are of const-qualified type, the
+ // program is ill-formed.
+ // FIXME: DPG thinks it is very fishy that C++0x disables this.
+ } else {
+ InitializedEntity Entity = InitializedEntity::InitializeVariable(Var);
+ InitializationKind Kind
+ = InitializationKind::CreateDefault(Var->getLocation());
- InitializationSequence InitSeq(*this, Entity, Kind, 0, 0);
- OwningExprResult Init = InitSeq.Perform(*this, Entity, Kind,
- MultiExprArg(*this, 0, 0));
- if (Init.isInvalid())
- Var->setInvalidDecl();
- else {
- if (Init.get())
+ InitializationSequence InitSeq(*this, Entity, Kind, 0, 0);
+ OwningExprResult Init = InitSeq.Perform(*this, Entity, Kind,
+ MultiExprArg(*this, 0, 0));
+ if (Init.isInvalid())
+ Var->setInvalidDecl();
+ else if (Init.get())
Var->setInit(MaybeCreateCXXExprWithTemporaries(Init.takeAs<Expr>()));
-
- if (getLangOptions().CPlusPlus)
- if (const RecordType *Record
- = Context.getBaseElementType(Type)->getAs<RecordType>())
- FinalizeVarWithDestructor(Var, Record);
}
+
+ if (!Var->isInvalidDecl() && getLangOptions().CPlusPlus && Record)
+ FinalizeVarWithDestructor(Var, Record);
}
}
@@ -5030,7 +5027,7 @@ void Sema::ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagD,
// Exit this scope of this tag's definition.
PopDeclContext();
- if (isa<CXXRecordDecl>(Tag) && !Tag->getDeclContext()->isRecord())
+ if (isa<CXXRecordDecl>(Tag) && !Tag->getLexicalDeclContext()->isRecord())
RecordDynamicClassesWithNoKeyFunction(*this, cast<CXXRecordDecl>(Tag),
RBraceLoc);
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 0708d41..e694cb4 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -665,22 +665,29 @@ void Sema::ActOnBaseSpecifiers(DeclPtrTy ClassDecl, BaseTy **Bases,
(CXXBaseSpecifier**)(Bases), NumBases);
}
+static CXXRecordDecl *GetClassForType(QualType T) {
+ if (const RecordType *RT = T->getAs<RecordType>())
+ return cast<CXXRecordDecl>(RT->getDecl());
+ else if (const InjectedClassNameType *ICT = T->getAs<InjectedClassNameType>())
+ return ICT->getDecl();
+ else
+ return 0;
+}
+
/// \brief Determine whether the type \p Derived is a C++ class that is
/// derived from the type \p Base.
bool Sema::IsDerivedFrom(QualType Derived, QualType Base) {
if (!getLangOptions().CPlusPlus)
return false;
-
- const RecordType *DerivedRT = Derived->getAs<RecordType>();
- if (!DerivedRT)
+
+ CXXRecordDecl *DerivedRD = GetClassForType(Derived);
+ if (!DerivedRD)
return false;
- const RecordType *BaseRT = Base->getAs<RecordType>();
- if (!BaseRT)
+ CXXRecordDecl *BaseRD = GetClassForType(Base);
+ if (!BaseRD)
return false;
- CXXRecordDecl *DerivedRD = cast<CXXRecordDecl>(DerivedRT->getDecl());
- CXXRecordDecl *BaseRD = cast<CXXRecordDecl>(BaseRT->getDecl());
// FIXME: instantiate DerivedRD if necessary. We need a PoI for this.
return DerivedRD->hasDefinition() && DerivedRD->isDerivedFrom(BaseRD);
}
@@ -691,16 +698,14 @@ bool Sema::IsDerivedFrom(QualType Derived, QualType Base, CXXBasePaths &Paths) {
if (!getLangOptions().CPlusPlus)
return false;
- const RecordType *DerivedRT = Derived->getAs<RecordType>();
- if (!DerivedRT)
+ CXXRecordDecl *DerivedRD = GetClassForType(Derived);
+ if (!DerivedRD)
return false;
- const RecordType *BaseRT = Base->getAs<RecordType>();
- if (!BaseRT)
+ CXXRecordDecl *BaseRD = GetClassForType(Base);
+ if (!BaseRD)
return false;
- CXXRecordDecl *DerivedRD = cast<CXXRecordDecl>(DerivedRT->getDecl());
- CXXRecordDecl *BaseRD = cast<CXXRecordDecl>(BaseRT->getDecl());
return DerivedRD->isDerivedFrom(BaseRD, Paths);
}
@@ -1083,6 +1088,9 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
// specialization, we take it as a type name.
BaseType = CheckTypenameType((NestedNameSpecifier *)SS.getScopeRep(),
*MemberOrBase, SS.getRange());
+ if (BaseType.isNull())
+ return true;
+
R.clear();
}
}
@@ -4526,20 +4534,23 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType,
OverloadCandidateSet::iterator Best;
switch (BestViableFunction(CandidateSet, DeclLoc, Best)) {
case OR_Success:
+ // C++ [over.ics.ref]p1:
+ //
+ // [...] If the parameter binds directly to the result of
+ // applying a conversion function to the argument
+ // expression, the implicit conversion sequence is a
+ // user-defined conversion sequence (13.3.3.1.2), with the
+ // second standard conversion sequence either an identity
+ // conversion or, if the conversion function returns an
+ // entity of a type that is a derived class of the parameter
+ // type, a derived-to-base Conversion.
+ if (!Best->FinalConversion.DirectBinding)
+ break;
+
// This is a direct binding.
BindsDirectly = true;
if (ICS) {
- // C++ [over.ics.ref]p1:
- //
- // [...] If the parameter binds directly to the result of
- // applying a conversion function to the argument
- // expression, the implicit conversion sequence is a
- // user-defined conversion sequence (13.3.3.1.2), with the
- // second standard conversion sequence either an identity
- // conversion or, if the conversion function returns an
- // entity of a type that is a derived class of the parameter
- // type, a derived-to-base Conversion.
ICS->setUserDefined();
ICS->UserDefined.Before = Best->Conversions[0].Standard;
ICS->UserDefined.After = Best->FinalConversion;
@@ -5189,21 +5200,28 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, QualType ExDeclType,
Invalid = true;
}
+ // GCC allows catching pointers and references to incomplete types
+ // as an extension; so do we, but we warn by default.
+
QualType BaseType = ExDeclType;
int Mode = 0; // 0 for direct type, 1 for pointer, 2 for reference
unsigned DK = diag::err_catch_incomplete;
+ bool IncompleteCatchIsInvalid = true;
if (const PointerType *Ptr = BaseType->getAs<PointerType>()) {
BaseType = Ptr->getPointeeType();
Mode = 1;
- DK = diag::err_catch_incomplete_ptr;
+ DK = diag::ext_catch_incomplete_ptr;
+ IncompleteCatchIsInvalid = false;
} else if (const ReferenceType *Ref = BaseType->getAs<ReferenceType>()) {
// For the purpose of error recovery, we treat rvalue refs like lvalue refs.
BaseType = Ref->getPointeeType();
Mode = 2;
- DK = diag::err_catch_incomplete_ref;
+ DK = diag::ext_catch_incomplete_ref;
+ IncompleteCatchIsInvalid = false;
}
if (!Invalid && (Mode == 0 || !BaseType->isVoidType()) &&
- !BaseType->isDependentType() && RequireCompleteType(Loc, BaseType, DK))
+ !BaseType->isDependentType() && RequireCompleteType(Loc, BaseType, DK) &&
+ IncompleteCatchIsInvalid)
Invalid = true;
if (!Invalid && !ExDeclType->isDependentType() &&
@@ -5889,10 +5907,13 @@ void Sema::MaybeMarkVirtualMembersReferenced(SourceLocation Loc,
// We will need to mark all of the virtual members as referenced to build the
// vtable.
- // We actually call MarkVirtualMembersReferenced instead of adding to
- // ClassesWithUnmarkedVirtualMembers because this marking is needed by
- // codegen that will happend before we finish parsing the file.
- if (needsVtable(MD, Context))
+ if (!needsVtable(MD, Context))
+ return;
+
+ TemplateSpecializationKind kind = RD->getTemplateSpecializationKind();
+ if (kind == TSK_ImplicitInstantiation)
+ ClassesWithUnmarkedVirtualMembers.push_back(std::make_pair(RD, Loc));
+ else
MarkVirtualMembersReferenced(Loc, RD);
}
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 149fe15..762ef38 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -1681,7 +1681,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
// for this class.
GetterMethod = ObjCMethodDecl::Create(Context, property->getLocation(),
property->getLocation(), property->getGetterName(),
- property->getType(), CD, true, false, true,
+ property->getType(), 0, CD, true, false, true,
(property->getPropertyImplementation() ==
ObjCPropertyDecl::Optional) ?
ObjCMethodDecl::Optional :
@@ -1703,7 +1703,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
SetterMethod = ObjCMethodDecl::Create(Context, property->getLocation(),
property->getLocation(),
property->getSetterName(),
- Context.VoidTy, CD, true, false, true,
+ Context.VoidTy, 0, CD, true, false, true,
(property->getPropertyImplementation() ==
ObjCPropertyDecl::Optional) ?
ObjCMethodDecl::Optional :
@@ -1992,8 +1992,9 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
}
QualType resultDeclType;
+ TypeSourceInfo *ResultTInfo = 0;
if (ReturnType) {
- resultDeclType = GetTypeFromParser(ReturnType);
+ resultDeclType = GetTypeFromParser(ReturnType, &ResultTInfo);
// Methods cannot return interface types. All ObjC objects are
// passed by reference.
@@ -2007,6 +2008,7 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
ObjCMethodDecl* ObjCMethod =
ObjCMethodDecl::Create(Context, MethodLoc, EndLoc, Sel, resultDeclType,
+ ResultTInfo,
cast<DeclContext>(ClassDecl),
MethodType == tok::minus, isVariadic,
false,
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 10001c3..2249579 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -6593,7 +6593,8 @@ Sema::ActOnStmtExpr(SourceLocation LPLoc, StmtArg substmt,
assert(SubStmt && isa<CompoundStmt>(SubStmt) && "Invalid action invocation!");
CompoundStmt *Compound = cast<CompoundStmt>(SubStmt);
- bool isFileScope = getCurFunctionOrMethodDecl() == 0;
+ bool isFileScope
+ = (getCurFunctionOrMethodDecl() == 0) && (getCurBlock() == 0);
if (isFileScope)
return ExprError(Diag(LPLoc, diag::err_stmtexpr_file_scope));
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 309da29..b9c8afa 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -172,14 +172,6 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
if (TypeDecl *Type = Found.getAsSingle<TypeDecl>()) {
QualType T = Context.getTypeDeclType(Type);
- // If we found the injected-class-name of a class template, retrieve the
- // type of that template.
- // FIXME: We really shouldn't need to do this.
- if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Type))
- if (Record->isInjectedClassName())
- if (Record->getDescribedClassTemplate())
- T = Record->getDescribedClassTemplate()
- ->getInjectedClassNameType(Context);
if (SearchType.isNull() || SearchType->isDependentType() ||
Context.hasSameUnqualifiedType(T, SearchType)) {
@@ -200,16 +192,8 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
if (SS.isSet()) {
if (DeclContext *Ctx = computeDeclContext(SS, EnteringContext)) {
// Figure out the type of the context, if it has one.
- if (ClassTemplateSpecializationDecl *Spec
- = dyn_cast<ClassTemplateSpecializationDecl>(Ctx))
- MemberOfType = Context.getTypeDeclType(Spec);
- else if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx)) {
- if (Record->getDescribedClassTemplate())
- MemberOfType = Record->getDescribedClassTemplate()
- ->getInjectedClassNameType(Context);
- else
- MemberOfType = Context.getTypeDeclType(Record);
- }
+ if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx))
+ MemberOfType = Context.getTypeDeclType(Record);
}
}
if (MemberOfType.isNull())
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 3a05241..c60455d 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -470,13 +470,13 @@ Sema::ExprResult Sema::ActOnClassMessage(
// now, we simply pass the "super" identifier through (which isn't consistent
// with instance methods.
if (isSuper)
- return new (Context) ObjCMessageExpr(Context, receiverName, Sel, returnType,
- Method, lbrac, rbrac, ArgExprs,
- NumArgs);
+ return new (Context) ObjCMessageExpr(Context, receiverName, receiverLoc,
+ Sel, returnType, Method, lbrac, rbrac,
+ ArgExprs, NumArgs);
else
- return new (Context) ObjCMessageExpr(Context, ClassDecl, Sel, returnType,
- Method, lbrac, rbrac, ArgExprs,
- NumArgs);
+ return new (Context) ObjCMessageExpr(Context, ClassDecl, receiverLoc,
+ Sel, returnType, Method, lbrac, rbrac,
+ ArgExprs, NumArgs);
}
// ActOnInstanceMessage - used for both unary and keyword messages.
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index bf9f73c..3540cd0 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -18,6 +18,7 @@
#include "SemaInit.h"
#include "Lookup.h"
#include "Sema.h"
+#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/Designator.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ExprCXX.h"
@@ -497,6 +498,20 @@ void InitListChecker::CheckImplicitInitList(const InitializedEntity &Entity,
= ParentIList->getInit(EndIndex)->getSourceRange().getEnd();
StructuredSubobjectInitList->setRBraceLoc(EndLoc);
}
+
+ // Warn about missing braces.
+ if (T->isArrayType() || T->isRecordType()) {
+ SemaRef.Diag(StructuredSubobjectInitList->getLocStart(),
+ diag::warn_missing_braces)
+ << StructuredSubobjectInitList->getSourceRange()
+ << CodeModificationHint::CreateInsertion(
+ StructuredSubobjectInitList->getLocStart(),
+ "{")
+ << CodeModificationHint::CreateInsertion(
+ SemaRef.PP.getLocForEndOfToken(
+ StructuredSubobjectInitList->getLocEnd()),
+ "}");
+ }
}
void InitListChecker::CheckExplicitInitList(const InitializedEntity &Entity,
@@ -2258,10 +2273,17 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
Sema::ReferenceCompareResult NewRefRelationship
= S.CompareReferenceRelationship(DeclLoc, T1, T2.getNonReferenceType(),
NewDerivedToBase);
- assert(NewRefRelationship != Sema::Ref_Incompatible &&
- "Overload resolution picked a bad conversion function");
- (void)NewRefRelationship;
- if (NewDerivedToBase)
+ if (NewRefRelationship == Sema::Ref_Incompatible) {
+ // If the type we've converted to is not reference-related to the
+ // type we're looking for, then there is another conversion step
+ // we need to perform to produce a temporary of the right type
+ // that we'll be binding to.
+ ImplicitConversionSequence ICS;
+ ICS.setStandard();
+ ICS.Standard = Best->FinalConversion;
+ T2 = ICS.Standard.getToType(2);
+ Sequence.AddConversionSequenceStep(ICS, T2);
+ } else if (NewDerivedToBase)
Sequence.AddDerivedToBaseCastStep(
S.Context.getQualifiedType(T1,
T2.getNonReferenceType().getQualifiers()),
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 0321958..7c4cab1 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -871,10 +871,8 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
NewClass->setDescribedClassTemplate(NewTemplate);
// Build the type for the class template declaration now.
- QualType T =
- Context.getTypeDeclType(NewClass,
- PrevClassTemplate?
- PrevClassTemplate->getTemplatedDecl() : 0);
+ QualType T = NewTemplate->getInjectedClassNameSpecialization(Context);
+ T = Context.getInjectedClassNameType(NewClass, T);
assert(T->isDependentType() && "Class template type is not dependent?");
(void)T;
@@ -1306,7 +1304,7 @@ Sema::MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc,
TemplateParameterList *ExpectedTemplateParams = 0;
// Is this template-id naming the primary template?
if (Context.hasSameType(TemplateId,
- ClassTemplate->getInjectedClassNameType(Context)))
+ ClassTemplate->getInjectedClassNameSpecialization(Context)))
ExpectedTemplateParams = ClassTemplate->getTemplateParameters();
// ... or a partial specialization?
else if (ClassTemplatePartialSpecializationDecl *PartialSpec
@@ -1431,6 +1429,8 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
}
CanonType = Context.getTypeDeclType(Decl);
+ assert(isa<RecordType>(CanonType) &&
+ "type of non-dependent specialization is not a RecordType");
}
// Build the fully-sugared type for this class template
@@ -3488,6 +3488,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
ClassTemplate,
Converted,
TemplateArgs,
+ CanonType,
PrevPartial);
if (PrevPartial) {
@@ -3609,8 +3610,9 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
// actually wrote the specialization, rather than formatting the
// name based on the "canonical" representation used to store the
// template arguments in the specialization.
- QualType WrittenTy
- = Context.getTemplateSpecializationType(Name, TemplateArgs, CanonType);
+ TypeSourceInfo *WrittenTy
+ = Context.getTemplateSpecializationTypeInfo(Name, TemplateNameLoc,
+ TemplateArgs, CanonType);
if (TUK != TUK_Friend)
Specialization->setTypeAsWritten(WrittenTy);
TemplateArgsIn.release();
@@ -3632,7 +3634,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
if (TUK == TUK_Friend) {
FriendDecl *Friend = FriendDecl::Create(Context, CurContext,
TemplateNameLoc,
- WrittenTy.getTypePtr(),
+ WrittenTy->getType().getTypePtr(),
/*FIXME:*/KWLoc);
Friend->setAccess(AS_public);
CurContext->addDecl(Friend);
@@ -4344,8 +4346,9 @@ Sema::ActOnExplicitInstantiation(Scope *S,
// the explicit instantiation, rather than formatting the name based
// on the "canonical" representation used to store the template
// arguments in the specialization.
- QualType WrittenTy
- = Context.getTemplateSpecializationType(Name, TemplateArgs,
+ TypeSourceInfo *WrittenTy
+ = Context.getTemplateSpecializationTypeInfo(Name, TemplateNameLoc,
+ TemplateArgs,
Context.getTypeDeclType(Specialization));
Specialization->setTypeAsWritten(WrittenTy);
TemplateArgsIn.release();
@@ -4992,6 +4995,9 @@ CurrentInstantiationRebuilder::TransformTypenameType(TypeLocBuilder &TLB,
Result = getDerived().RebuildTypenameType(NNS, T->getIdentifier(),
SourceRange(TL.getNameLoc()));
+ if (Result.isNull())
+ return QualType();
+
TypenameTypeLoc NewTL = TLB.push<TypenameTypeLoc>(Result);
NewTL.setNameLoc(TL.getNameLoc());
return Result;
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 7f16400..326519d 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -625,6 +625,15 @@ DeduceTemplateArguments(Sema &S,
return Sema::TDK_Success;
}
+ case Type::InjectedClassName: {
+ // Treat a template's injected-class-name as if the template
+ // specialization type had been used.
+ Param = cast<InjectedClassNameType>(Param)->getUnderlyingType();
+ assert(isa<TemplateSpecializationType>(Param) &&
+ "injected class name is not a template specialization type");
+ // fall through
+ }
+
// template-name<T> (where template-name refers to a class template)
// template-name<i>
// TT<T>
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 3a6b4cb..cf8d38c 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -621,7 +621,8 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
Inst->setInstantiatedFromMemberTemplate(D);
// Trigger creation of the type for the instantiation.
- SemaRef.Context.getTypeDeclType(RecordInst);
+ SemaRef.Context.getInjectedClassNameType(RecordInst,
+ Inst->getInjectedClassNameSpecialization(SemaRef.Context));
// Finish handling of friends.
if (Inst->getFriendObjectKind()) {
@@ -1462,8 +1463,10 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
// actually wrote the specialization, rather than formatting the
// name based on the "canonical" representation used to store the
// template arguments in the specialization.
- QualType WrittenTy
- = SemaRef.Context.getTemplateSpecializationType(TemplateName(ClassTemplate),
+ TypeSourceInfo *WrittenTy
+ = SemaRef.Context.getTemplateSpecializationTypeInfo(
+ TemplateName(ClassTemplate),
+ PartialSpec->getLocation(),
InstTemplateArgs,
CanonType);
@@ -1499,6 +1502,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
ClassTemplate,
Converted,
InstTemplateArgs,
+ CanonType,
0);
InstPartialSpec->setInstantiatedFromMember(PartialSpec);
InstPartialSpec->setTypeAsWritten(WrittenTy);
@@ -2236,12 +2240,18 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
ClassTemplateDecl *ClassTemplate = Record->getDescribedClassTemplate();
if (ClassTemplate) {
- T = ClassTemplate->getInjectedClassNameType(Context);
+ T = ClassTemplate->getInjectedClassNameSpecialization(Context);
} else if (ClassTemplatePartialSpecializationDecl *PartialSpec
= dyn_cast<ClassTemplatePartialSpecializationDecl>(Record)) {
- T = Context.getTypeDeclType(Record);
ClassTemplate = PartialSpec->getSpecializedTemplate();
- }
+
+ // If we call SubstType with an InjectedClassNameType here we
+ // can end up in an infinite loop.
+ T = Context.getTypeDeclType(Record);
+ assert(isa<InjectedClassNameType>(T) &&
+ "type of partial specialization is not an InjectedClassNameType");
+ T = cast<InjectedClassNameType>(T)->getUnderlyingType();
+ }
if (!T.isNull()) {
// Substitute into the injected-class-name to get the type
@@ -2308,16 +2318,16 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
// so now we need to look into the instantiated parent context to
// find the instantiation of the declaration D.
- // If our context is a class template specialization, we may need
- // to instantiate it before performing lookup into that context.
- if (ClassTemplateSpecializationDecl *Spec
- = dyn_cast<ClassTemplateSpecializationDecl>(ParentDC)) {
+ // If our context used to be dependent, we may need to instantiate
+ // it before performing lookup into that context.
+ if (CXXRecordDecl *Spec = dyn_cast<CXXRecordDecl>(ParentDC)) {
if (!Spec->isDependentContext()) {
QualType T = Context.getTypeDeclType(Spec);
- if (const TagType *Tag = T->getAs<TagType>())
- if (!Tag->isBeingDefined() &&
- RequireCompleteType(Loc, T, diag::err_incomplete_type))
- return 0;
+ const RecordType *Tag = T->getAs<RecordType>();
+ assert(Tag && "type of non-dependent record is not a RecordType");
+ if (!Tag->isBeingDefined() &&
+ RequireCompleteType(Loc, T, diag::err_incomplete_type))
+ return 0;
}
}
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 24ea62c..17f9419 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -2823,6 +2823,20 @@ QualType TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
return Result;
}
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformInjectedClassNameType(
+ TypeLocBuilder &TLB,
+ InjectedClassNameTypeLoc TL,
+ QualType ObjectType) {
+ Decl *D = getDerived().TransformDecl(TL.getNameLoc(),
+ TL.getTypePtr()->getDecl());
+ if (!D) return QualType();
+
+ QualType T = SemaRef.Context.getTypeDeclType(cast<TypeDecl>(D));
+ TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc());
+ return T;
+}
+
template<typename Derived>
QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c
index a002174..9a266c9 100644
--- a/test/Analysis/dead-stores.c
+++ b/test/Analysis/dead-stores.c
@@ -1,8 +1,8 @@
-// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code %s
-// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code %s
-// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code %s
-// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code %s
-// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
void f1() {
int k, y;
@@ -377,7 +377,7 @@ void f24_A(int y) {
// FIXME: One day this should be reported as dead since 'z = x + y' is dead.
int x = (y > 2); // no-warning
^ {
- int z = x + y; // FIXME: Eventually this should be reported as a dead store.
+ int z = x + y; // expected-warning{{Value stored to 'z' during its initialization is never read}}
}();
}
@@ -429,3 +429,17 @@ int f25_b(int y) {
return z;
}
+int f26_nestedblocks() {
+ int z;
+ z = 1;
+ __block int y = 0;
+ ^{
+ int k;
+ k = 1; // expected-warning{{Value stored to 'k' is never read}}
+ ^{
+ y = z + 1;
+ }();
+ }();
+ return y;
+}
+
diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c
index 3cce1b0..21b6d46 100644
--- a/test/Analysis/malloc.c
+++ b/test/Analysis/malloc.c
@@ -61,3 +61,9 @@ void pr6069() {
void pr6293() {
free(0);
}
+
+void f7() {
+ char *x = (char*) malloc(4);
+ free(x);
+ x[0] = 'a'; // expected-warning{{Use dynamically allocated memory after it is freed.}}
+}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 245fe1f..6bb5b6c 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -9,6 +9,7 @@ set(CLANG_TEST_DIRECTORIES
"Driver"
"FixIt"
"Frontend"
+ "Headers"
"Index"
"Lexer"
"Misc"
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp
index 7a62100..f9bac40 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/namespace.qual/p2.cpp
@@ -57,9 +57,9 @@ void test3() {
int i = Ints::zero;
Numbers2::f(i);
- Numbers2::g(i); // expected-error {{no viable conversion from 'int' to 'struct Numbers::Number' is possible}}
+ Numbers2::g(i); // expected-error {{no viable conversion from 'int' to 'Numbers::Number'}}
float f = Floats::zero;
Numbers2::f(f);
- Numbers2::g(f); // expected-error {{no viable conversion from 'float' to 'struct Numbers::Number' is possible}}
+ Numbers2::g(f); // expected-error {{no viable conversion from 'float' to 'Numbers::Number'}}
}
diff --git a/test/CXX/class.access/class.friend/p1.cpp b/test/CXX/class.access/class.friend/p1.cpp
index 22f77b0..a06fb2e 100644
--- a/test/CXX/class.access/class.friend/p1.cpp
+++ b/test/CXX/class.access/class.friend/p1.cpp
@@ -22,10 +22,10 @@ void test1() {
S s;
g()->f();
S::f();
- X::g(); // expected-error{{no member named 'g' in 'struct X'}}
- X::S x_s; // expected-error{{no member named 'S' in 'struct X'}}
+ X::g(); // expected-error{{no member named 'g' in 'X'}}
+ X::S x_s; // expected-error{{no member named 'S' in 'X'}}
X x;
- x.g(); // expected-error{{no member named 'g' in 'struct X'}}
+ x.g(); // expected-error{{no member named 'g' in 'X'}}
}
// Test that we recurse through namespaces to find already declared names, but
@@ -46,17 +46,17 @@ namespace N {
g()->f();
S s;
S::f();
- X::g(); // expected-error{{no member named 'g' in 'struct N::X'}}
- X::S x_s; // expected-error{{no member named 'S' in 'struct N::X'}}
+ X::g(); // expected-error{{no member named 'g' in 'N::X'}}
+ X::S x_s; // expected-error{{no member named 'S' in 'N::X'}}
X x;
- x.g(); // expected-error{{no member named 'g' in 'struct N::X'}}
+ x.g(); // expected-error{{no member named 'g' in 'N::X'}}
g2();
S2 s2;
::g2(); // expected-error{{no member named 'g2' in the global namespace}}
::S2 g_s2; // expected-error{{no member named 'S2' in the global namespace}}
- X::g2(); // expected-error{{no member named 'g2' in 'struct N::X'}}
- X::S2 x_s2; // expected-error{{no member named 'S2' in 'struct N::X'}}
- x.g2(); // expected-error{{no member named 'g2' in 'struct N::X'}}
+ X::g2(); // expected-error{{no member named 'g2' in 'N::X'}}
+ X::S2 x_s2; // expected-error{{no member named 'S2' in 'N::X'}}
+ x.g2(); // expected-error{{no member named 'g2' in 'N::X'}}
}
}
diff --git a/test/CXX/class/class.friend/p1.cpp b/test/CXX/class/class.friend/p1.cpp
index 886fef5..3ad4a5f 100644
--- a/test/CXX/class/class.friend/p1.cpp
+++ b/test/CXX/class/class.friend/p1.cpp
@@ -67,7 +67,7 @@ class A {
class facet {};
};
-A::UndeclaredSoFar y; // expected-error {{no type named 'UndeclaredSoFar' in 'class A'}}
+A::UndeclaredSoFar y; // expected-error {{no type named 'UndeclaredSoFar' in 'A'}}
class PreDeclared;
diff --git a/test/CXX/class/class.local/p2.cpp b/test/CXX/class/class.local/p2.cpp
index 8d281a5..2b1359c 100644
--- a/test/CXX/class/class.local/p2.cpp
+++ b/test/CXX/class/class.local/p2.cpp
@@ -7,5 +7,5 @@ void f() {
B b;
- A *a = &b; // expected-error{{cannot cast 'struct B' to its private base class 'struct A'}}
+ A *a = &b; // expected-error{{cannot cast 'B' to its private base class 'A'}}
}
diff --git a/test/CXX/class/class.union/p1.cpp b/test/CXX/class/class.union/p1.cpp
index 8794648..f53783e 100644
--- a/test/CXX/class/class.union/p1.cpp
+++ b/test/CXX/class/class.union/p1.cpp
@@ -7,30 +7,30 @@ class Okay {
};
class Virtual {
- virtual void foo() { abort(); } // expected-note 3 {{because type 'class Virtual' has a virtual member function}}
+ virtual void foo() { abort(); } // expected-note 3 {{because type 'Virtual' has a virtual member function}}
};
-class VirtualBase : virtual Okay { // expected-note 3 {{because type 'class VirtualBase' has a virtual base class}}
+class VirtualBase : virtual Okay { // expected-note 3 {{because type 'VirtualBase' has a virtual base class}}
};
class Ctor {
- Ctor() { abort(); } // expected-note 3 {{because type 'class Ctor' has a user-declared constructor}}
+ Ctor() { abort(); } // expected-note 3 {{because type 'Ctor' has a user-declared constructor}}
};
class Ctor2 {
- Ctor2(); // expected-note 3 {{because type 'class Ctor2' has a user-declared constructor}}
+ Ctor2(); // expected-note 3 {{because type 'Ctor2' has a user-declared constructor}}
};
class CopyCtor {
- CopyCtor(CopyCtor &cc) { abort(); } // expected-note 3 {{because type 'class CopyCtor' has a user-declared copy constructor}}
+ CopyCtor(CopyCtor &cc) { abort(); } // expected-note 3 {{because type 'CopyCtor' has a user-declared copy constructor}}
};
// FIXME: this should eventually trigger on the operator's declaration line
-class CopyAssign { // expected-note 3 {{because type 'class CopyAssign' has a user-declared copy assignment operator}}
+class CopyAssign { // expected-note 3 {{because type 'CopyAssign' has a user-declared copy assignment operator}}
CopyAssign& operator=(CopyAssign& CA) { abort(); }
};
class Dtor {
- ~Dtor() { abort(); } // expected-note 3 {{because type 'class Dtor' has a user-declared destructor}}
+ ~Dtor() { abort(); } // expected-note 3 {{because type 'Dtor' has a user-declared destructor}}
};
union U1 {
@@ -46,25 +46,25 @@ union U1 {
union U2 {
struct {
- Virtual v; // expected-note {{because type 'struct U2::<anonymous>' has a member with a non-trivial copy constructor}}
+ Virtual v; // expected-note {{because type 'U2::<anonymous>' has a member with a non-trivial copy constructor}}
} m1; // expected-error {{union member 'm1' has a non-trivial copy constructor}}
struct {
- VirtualBase vbase; // expected-note {{because type 'struct U2::<anonymous>' has a member with a non-trivial copy constructor}}
+ VirtualBase vbase; // expected-note {{because type 'U2::<anonymous>' has a member with a non-trivial copy constructor}}
} m2; // expected-error {{union member 'm2' has a non-trivial copy constructor}}
struct {
- Ctor ctor; // expected-note {{because type 'struct U2::<anonymous>' has a member with a non-trivial constructor}}
+ Ctor ctor; // expected-note {{because type 'U2::<anonymous>' has a member with a non-trivial constructor}}
} m3; // expected-error {{union member 'm3' has a non-trivial constructor}}
struct {
- Ctor2 ctor2; // expected-note {{because type 'struct U2::<anonymous>' has a member with a non-trivial constructor}}
+ Ctor2 ctor2; // expected-note {{because type 'U2::<anonymous>' has a member with a non-trivial constructor}}
} m3a; // expected-error {{union member 'm3a' has a non-trivial constructor}}
struct {
- CopyCtor copyctor; // expected-note {{because type 'struct U2::<anonymous>' has a member with a non-trivial copy constructor}}
+ CopyCtor copyctor; // expected-note {{because type 'U2::<anonymous>' has a member with a non-trivial copy constructor}}
} m4; // expected-error {{union member 'm4' has a non-trivial copy constructor}}
struct {
- CopyAssign copyassign; // expected-note {{because type 'struct U2::<anonymous>' has a member with a non-trivial copy assignment operator}}
+ CopyAssign copyassign; // expected-note {{because type 'U2::<anonymous>' has a member with a non-trivial copy assignment operator}}
} m5; // expected-error {{union member 'm5' has a non-trivial copy assignment operator}}
struct {
- Dtor dtor; // expected-note {{because type 'struct U2::<anonymous>' has a member with a non-trivial destructor}}
+ Dtor dtor; // expected-note {{because type 'U2::<anonymous>' has a member with a non-trivial destructor}}
} m6; // expected-error {{union member 'm6' has a non-trivial destructor}}
struct {
Okay okay;
@@ -72,19 +72,19 @@ union U2 {
};
union U3 {
- struct s1 : Virtual { // expected-note {{because type 'struct U3::s1' has a base class with a non-trivial copy constructor}}
+ struct s1 : Virtual { // expected-note {{because type 'U3::s1' has a base class with a non-trivial copy constructor}}
} m1; // expected-error {{union member 'm1' has a non-trivial copy constructor}}
- struct s2 : VirtualBase { // expected-note {{because type 'struct U3::s2' has a base class with a non-trivial copy constructor}}
+ struct s2 : VirtualBase { // expected-note {{because type 'U3::s2' has a base class with a non-trivial copy constructor}}
} m2; // expected-error {{union member 'm2' has a non-trivial copy constructor}}
- struct s3 : Ctor { // expected-note {{because type 'struct U3::s3' has a base class with a non-trivial constructor}}
+ struct s3 : Ctor { // expected-note {{because type 'U3::s3' has a base class with a non-trivial constructor}}
} m3; // expected-error {{union member 'm3' has a non-trivial constructor}}
- struct s3a : Ctor2 { // expected-note {{because type 'struct U3::s3a' has a base class with a non-trivial constructor}}
+ struct s3a : Ctor2 { // expected-note {{because type 'U3::s3a' has a base class with a non-trivial constructor}}
} m3a; // expected-error {{union member 'm3a' has a non-trivial constructor}}
- struct s4 : CopyCtor { // expected-note {{because type 'struct U3::s4' has a base class with a non-trivial copy constructor}}
+ struct s4 : CopyCtor { // expected-note {{because type 'U3::s4' has a base class with a non-trivial copy constructor}}
} m4; // expected-error {{union member 'm4' has a non-trivial copy constructor}}
- struct s5 : CopyAssign { // expected-note {{because type 'struct U3::s5' has a base class with a non-trivial copy assignment operator}}
+ struct s5 : CopyAssign { // expected-note {{because type 'U3::s5' has a base class with a non-trivial copy assignment operator}}
} m5; // expected-error {{union member 'm5' has a non-trivial copy assignment operator}}
- struct s6 : Dtor { // expected-note {{because type 'struct U3::s6' has a base class with a non-trivial destructor}}
+ struct s6 : Dtor { // expected-note {{because type 'U3::s6' has a base class with a non-trivial destructor}}
} m6; // expected-error {{union member 'm6' has a non-trivial destructor}}
struct s7 : Okay {
} m7;
diff --git a/test/CXX/conv/conv.mem/p4.cpp b/test/CXX/conv/conv.mem/p4.cpp
index 1ecbc47..42f6343 100644
--- a/test/CXX/conv/conv.mem/p4.cpp
+++ b/test/CXX/conv/conv.mem/p4.cpp
@@ -19,8 +19,8 @@ namespace test0 {
namespace test1 {
struct Derived : private Base {}; // expected-note 2 {{declared private here}}
void test() {
- int (Derived::*d) = data_ptr; // expected-error {{cannot cast private base class 'struct Base' to 'struct test1::Derived'}}
- int (Derived::*m)() = method_ptr; // expected-error {{cannot cast private base class 'struct Base' to 'struct test1::Derived'}}
+ int (Derived::*d) = data_ptr; // expected-error {{cannot cast private base class 'Base' to 'test1::Derived'}}
+ int (Derived::*m)() = method_ptr; // expected-error {{cannot cast private base class 'Base' to 'test1::Derived'}}
}
};
@@ -30,8 +30,8 @@ namespace test2 {
struct B : Base {};
struct Derived : A, B {};
void test() {
- int (Derived::*d) = data_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'struct Base' to pointer to member of derived class 'struct test2::Derived'}}
- int (Derived::*m)() = method_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'struct Base' to pointer to member of derived class 'struct test2::Derived'}}
+ int (Derived::*d) = data_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'test2::Derived':}}
+ int (Derived::*m)() = method_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'test2::Derived':}}
}
}
@@ -39,8 +39,8 @@ namespace test2 {
namespace test3 {
struct Derived : virtual Base {};
void test() {
- int (Derived::*d) = data_ptr; // expected-error {{conversion from pointer to member of class 'struct Base' to pointer to member of class 'struct test3::Derived' via virtual base 'struct Base' is not allowed}}
- int (Derived::*m)() = method_ptr; // expected-error {{conversion from pointer to member of class 'struct Base' to pointer to member of class 'struct test3::Derived' via virtual base 'struct Base' is not allowed}}
+ int (Derived::*d) = data_ptr; // expected-error {{conversion from pointer to member of class 'Base' to pointer to member of class 'test3::Derived' via virtual base 'Base' is not allowed}}
+ int (Derived::*m)() = method_ptr; // expected-error {{conversion from pointer to member of class 'Base' to pointer to member of class 'test3::Derived' via virtual base 'Base' is not allowed}}
}
}
@@ -49,8 +49,8 @@ namespace test4 {
struct A : Base {};
struct Derived : Base, virtual A {};
void test() {
- int (Derived::*d) = data_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'struct Base' to pointer to member of derived class 'struct test4::Derived'}}
- int (Derived::*m)() = method_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'struct Base' to pointer to member of derived class 'struct test4::Derived'}}
+ int (Derived::*d) = data_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'test4::Derived':}}
+ int (Derived::*m)() = method_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'test4::Derived':}}
}
}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp
index 7bfb655..f507eec 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.stc/p9.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -verify %s
-struct S; // expected-note {{forward declaration of 'struct S'}}
+struct S; // expected-note {{forward declaration of 'S'}}
extern S a;
extern S f(); // expected-note {{'f' declared here}}
extern void g(S a); // expected-note {{candidate function}}
@@ -8,5 +8,5 @@ extern void g(S a); // expected-note {{candidate function}}
void h() {
// FIXME: This diagnostic could be better.
g(a); // expected-error {{no matching function for call to 'g'}}
- f(); // expected-error {{calling 'f' with incomplete return type 'struct S'}}
+ f(); // expected-error {{calling 'f' with incomplete return type 'S'}}
}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp
index 7c63a79..d757adf 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp
@@ -16,10 +16,10 @@ struct B : A { } b;
// CHECK: example1
void example1() {
- // CHECK: struct A &ra =
+ // CHECK: A &ra =
// CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase> lvalue
A &ra = b;
- // CHECK: struct A const &rca =
+ // CHECK: A const &rca =
// CHECK: ImplicitCastExpr{{.*}}'struct A const' <NoOp>
// CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase>
const A& rca = b;
@@ -33,12 +33,12 @@ struct X {
// CHECK: example2
void example2() {
- // CHECK: struct A const &rca =
+ // CHECK: A const &rca =
// CHECK: ImplicitCastExpr{{.*}}'struct A const' <NoOp>
// CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase>
- // CHECK: CallExpr{{.*}}struct B
+ // CHECK: CallExpr{{.*}}B
const A &rca = f();
- // CHECK: struct A const &r =
+ // CHECK: A const &r =
// CHECK: ImplicitCastExpr{{.*}}'struct A const' <NoOp>
// CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase>
// CHECK: CXXMemberCallExpr{{.*}}'struct B'
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp
index d9c5d01..6a039b9 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp
@@ -51,10 +51,10 @@ void bind_lvalue_to_lvalue(Base b, Derived d,
Base &br1 = b;
Base &br2 = d;
Derived &dr1 = d;
- Derived &dr2 = b; // expected-error{{non-const lvalue reference to type 'struct Derived' cannot bind to a value of unrelated type 'struct Base'}}
+ Derived &dr2 = b; // expected-error{{non-const lvalue reference to type 'Derived' cannot bind to a value of unrelated type 'Base'}}
Base &br3 = bc; // expected-error{{drops qualifiers}}
Base &br4 = dc; // expected-error{{drops qualifiers}}
- Base &br5 = diamond; // expected-error{{ambiguous conversion from derived class 'struct Diamond' to base class 'struct Base'}}
+ Base &br5 = diamond; // expected-error{{ambiguous conversion from derived class 'Diamond' to base class 'Base':}}
int &ir = i;
long &lr = i; // expected-error{{non-const lvalue reference to type 'long' cannot bind to a value of unrelated type 'int'}}
}
@@ -64,8 +64,8 @@ void bind_lvalue_quals(volatile Base b, volatile Derived d,
volatile const int ivc) {
volatile Base &bvr1 = b;
volatile Base &bvr2 = d;
- volatile Base &bvr3 = bvc; // expected-error{{binding of reference to type 'struct Base volatile' to a value of type 'struct Base const volatile' drops qualifiers}}
- volatile Base &bvr4 = dvc; // expected-error{{binding of reference to type 'struct Base volatile' to a value of type 'struct Derived const volatile' drops qualifiers}}
+ volatile Base &bvr3 = bvc; // expected-error{{binding of reference to type 'Base volatile' to a value of type 'Base const volatile' drops qualifiers}}
+ volatile Base &bvr4 = dvc; // expected-error{{binding of reference to type 'Base volatile' to a value of type 'Derived const volatile' drops qualifiers}}
volatile int &ir = ivc; // expected-error{{binding of reference to type 'int volatile' to a value of type 'int const volatile' drops qualifiers}}
@@ -74,17 +74,17 @@ void bind_lvalue_quals(volatile Base b, volatile Derived d,
}
void bind_lvalue_to_rvalue() {
- Base &br1 = Base(); // expected-error{{non-const lvalue reference to type 'struct Base' cannot bind to a temporary of type 'struct Base'}}
- Base &br2 = Derived(); // expected-error{{non-const lvalue reference to type 'struct Base' cannot bind to a temporary of type 'struct Derived'}}
- const volatile Base &br3 = Base(); // expected-error{{volatile lvalue reference to type 'struct Base const volatile' cannot bind to a temporary of type 'struct Base'}}
- const volatile Base &br4 = Derived(); // expected-error{{volatile lvalue reference to type 'struct Base const volatile' cannot bind to a temporary of type 'struct Derived'}}
+ Base &br1 = Base(); // expected-error{{non-const lvalue reference to type 'Base' cannot bind to a temporary of type 'Base'}}
+ Base &br2 = Derived(); // expected-error{{non-const lvalue reference to type 'Base' cannot bind to a temporary of type 'Derived'}}
+ const volatile Base &br3 = Base(); // expected-error{{volatile lvalue reference to type 'Base const volatile' cannot bind to a temporary of type 'Base'}}
+ const volatile Base &br4 = Derived(); // expected-error{{volatile lvalue reference to type 'Base const volatile' cannot bind to a temporary of type 'Derived'}}
int &ir = 17; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}}
}
void bind_lvalue_to_unrelated(Unrelated ur) {
- Base &br1 = ur; // expected-error{{non-const lvalue reference to type 'struct Base' cannot bind to a value of unrelated type 'struct Unrelated'}}
- const volatile Base &br2 = ur; // expected-error{{volatile lvalue reference to type 'struct Base const volatile' cannot bind to a value of unrelated type 'struct Unrelated'}}
+ Base &br1 = ur; // expected-error{{non-const lvalue reference to type 'Base' cannot bind to a value of unrelated type 'Unrelated'}}
+ const volatile Base &br2 = ur; // expected-error{{volatile lvalue reference to type 'Base const volatile' cannot bind to a value of unrelated type 'Unrelated'}}
}
void bind_lvalue_to_conv_lvalue() {
@@ -97,7 +97,7 @@ void bind_lvalue_to_conv_lvalue() {
void bind_lvalue_to_conv_lvalue_ambig(ConvertibleToBothDerivedRef both) {
Derived &dr1 = both;
- Base &br1 = both; // expected-error{{reference initialization of type 'struct Base &' with initializer of type 'struct ConvertibleToBothDerivedRef' is ambiguous}}
+ Base &br1 = both; // expected-error{{reference initialization of type 'Base &' with initializer of type 'ConvertibleToBothDerivedRef' is ambiguous}}
}
struct IntBitfield {
@@ -118,8 +118,8 @@ void bind_const_lvalue_to_rvalue() {
const Base &br3 = create<const Base>();
const Base &br4 = create<const Derived>();
- const Base &br5 = create<const volatile Base>(); // expected-error{{binding of reference to type 'struct Base const' to a value of type 'struct Base const volatile' drops qualifiers}}
- const Base &br6 = create<const volatile Derived>(); // expected-error{{binding of reference to type 'struct Base const' to a value of type 'struct Derived const volatile' drops qualifiers}}
+ const Base &br5 = create<const volatile Base>(); // expected-error{{binding of reference to type 'Base const' to a value of type 'Base const volatile' drops qualifiers}}
+ const Base &br6 = create<const volatile Derived>(); // expected-error{{binding of reference to type 'Base const' to a value of type 'Derived const volatile' drops qualifiers}}
const int &ir = create<int>();
}
@@ -131,5 +131,5 @@ void bind_const_lvalue_to_class_conv_temporary() {
}
void bind_lvalue_to_conv_rvalue_ambig(ConvertibleToBothDerived both) {
const Derived &dr1 = both;
- const Base &br1 = both; // expected-error{{reference initialization of type 'struct Base const &' with initializer of type 'struct ConvertibleToBothDerived' is ambiguous}}
+ const Base &br1 = both; // expected-error{{reference initialization of type 'Base const &' with initializer of type 'ConvertibleToBothDerived' is ambiguous}}
}
diff --git a/test/CXX/dcl.decl/dcl.init/p6.cpp b/test/CXX/dcl.decl/dcl.init/p6.cpp
index f627a19..c542dac 100644
--- a/test/CXX/dcl.decl/dcl.init/p6.cpp
+++ b/test/CXX/dcl.decl/dcl.init/p6.cpp
@@ -5,11 +5,12 @@
// If a program calls for the default initialization of an object of a
// const-qualified type T, T shall be a class type with a
// user-provided default constructor.
-struct NoUserDefault { };
+struct MakeNonPOD { MakeNonPOD(); };
+struct NoUserDefault : public MakeNonPOD { };
struct HasUserDefault { HasUserDefault(); };
void test_const_default_init() {
- const NoUserDefault x1; // expected-error{{default initialization of an object of const type 'struct NoUserDefault const' requires a user-provided default constructor}}
+ const NoUserDefault x1; // expected-error{{default initialization of an object of const type 'NoUserDefault const' requires a user-provided default constructor}}
const HasUserDefault x2;
const int x3; // expected-error{{default initialization of an object of const type 'int const'}}
}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp
index 561e26b..7e35788 100644
--- a/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p3.cpp
@@ -16,11 +16,11 @@ void f() {
int b;
A a(b);
- int A::*ip = &A::s; // expected-error {{cannot initialize a variable of type 'int class A::*' with an rvalue of type 'int *'}}
+ int A::*ip = &A::s; // expected-error {{cannot initialize a variable of type 'int A::*' with an rvalue of type 'int *'}}
a.*&A::s = 10; // expected-error{{right hand operand to .* has non pointer-to-member type 'int *'}}
a.*&A::i = 10; // expected-error{{cannot form a pointer-to-member to member 'i' of reference type 'int &'}}
- ft(a); // expected-note{{in instantiation of function template specialization 'ft<class A>' requested here}}
+ ft(a); // expected-note{{in instantiation of function template specialization 'ft<A>' requested here}}
void A::*p = 0; // expected-error{{'p' declared as a member pointer to void}}
}
diff --git a/test/CodeCompletion/call.cpp b/test/CodeCompletion/call.cpp
index 5467717..04d2a2f 100644
--- a/test/CodeCompletion/call.cpp
+++ b/test/CodeCompletion/call.cpp
@@ -18,10 +18,10 @@ void f();
void test() {
f(Y(), 0, 0);
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:19:9 %s -o - | FileCheck -check-prefix=CC1 %s
- // CHECK-CC1: f(struct N::Y y, <#int ZZ#>)
+ // CHECK-CC1: f(N::Y y, <#int ZZ#>)
// CHECK-CC1-NEXT: f(int i, <#int j#>, int k)
// CHECK-CC1-NEXT: f(float x, <#float y#>)
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:19:13 %s -o - | FileCheck -check-prefix=CC2 %s
- // CHECK-CC2-NOT: f(struct N::Y y, int ZZ)
+ // CHECK-CC2-NOT: f(N::Y y, int ZZ)
// CHECK-CC2: f(int i, int j, <#int k#>)
}
diff --git a/test/CodeCompletion/enum-switch-case-qualified.cpp b/test/CodeCompletion/enum-switch-case-qualified.cpp
index b9efcb4..e74ec9b 100644
--- a/test/CodeCompletion/enum-switch-case-qualified.cpp
+++ b/test/CodeCompletion/enum-switch-case-qualified.cpp
@@ -22,11 +22,11 @@ void test(enum N::C::Color color) {
switch (color) {
case
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:23:8 %s -o - | FileCheck -check-prefix=CC1 %s
- // CHECK-CC1: Blue : [#enum M::N::C::Color#]N::C::Blue
- // CHECK-CC1-NEXT: Green : [#enum M::N::C::Color#]N::C::Green
- // CHECK-CC1-NEXT: Indigo : [#enum M::N::C::Color#]N::C::Indigo
- // CHECK-CC1-NEXT: Orange : [#enum M::N::C::Color#]N::C::Orange
- // CHECK-CC1-NEXT: Red : [#enum M::N::C::Color#]N::C::Red
- // CHECK-CC1-NEXT: Violet : [#enum M::N::C::Color#]N::C::Violet
- // CHECK-CC1: Yellow : [#enum M::N::C::Color#]N::C::Yellow
+ // CHECK-CC1: Blue : [#M::N::C::Color#]N::C::Blue
+ // CHECK-CC1-NEXT: Green : [#M::N::C::Color#]N::C::Green
+ // CHECK-CC1-NEXT: Indigo : [#M::N::C::Color#]N::C::Indigo
+ // CHECK-CC1-NEXT: Orange : [#M::N::C::Color#]N::C::Orange
+ // CHECK-CC1-NEXT: Red : [#M::N::C::Color#]N::C::Red
+ // CHECK-CC1-NEXT: Violet : [#M::N::C::Color#]N::C::Violet
+ // CHECK-CC1: Yellow : [#M::N::C::Color#]N::C::Yellow
diff --git a/test/CodeCompletion/enum-switch-case.cpp b/test/CodeCompletion/enum-switch-case.cpp
index 412f5f2..2677f33 100644
--- a/test/CodeCompletion/enum-switch-case.cpp
+++ b/test/CodeCompletion/enum-switch-case.cpp
@@ -20,9 +20,9 @@ void test(enum N::Color color) {
case
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:21:8 %s -o - | FileCheck -check-prefix=CC1 %s
- // CHECK-CC1: Blue : [#enum N::Color#]N::Blue
- // CHECK-CC1-NEXT: Green : [#enum N::Color#]N::Green
- // CHECK-CC1-NEXT: Indigo : [#enum N::Color#]N::Indigo
- // CHECK-CC1-NEXT: Orange : [#enum N::Color#]N::Orange
- // CHECK-CC1-NEXT: Violet : [#enum N::Color#]N::Violet
+ // CHECK-CC1: Blue : [#N::Color#]N::Blue
+ // CHECK-CC1-NEXT: Green : [#N::Color#]N::Green
+ // CHECK-CC1-NEXT: Indigo : [#N::Color#]N::Indigo
+ // CHECK-CC1-NEXT: Orange : [#N::Color#]N::Orange
+ // CHECK-CC1-NEXT: Violet : [#N::Color#]N::Violet
diff --git a/test/CodeGen/2010-03-09-DbgInfo.c b/test/CodeGen/2010-03-09-DbgInfo.c
new file mode 100644
index 0000000..04ee02e
--- /dev/null
+++ b/test/CodeGen/2010-03-09-DbgInfo.c
@@ -0,0 +1,2 @@
+// RUN: %clang -dA -S -O0 -g %s -o - | grep DW_TAG_variable
+unsigned char ctable1[1] = { 0001 };
diff --git a/test/CodeGen/init.c b/test/CodeGen/init.c
index f6b3536..13ffad1 100644
--- a/test/CodeGen/init.c
+++ b/test/CodeGen/init.c
@@ -29,3 +29,14 @@ int f4() {
static const int g4 = 12;
return g4;
}
+
+// PR6537
+typedef union vec3 {
+ struct { double x, y, z; };
+ double component[3];
+} vec3;
+vec3 f5(vec3 value) {
+ return (vec3) {{
+ .x = value.x
+ }};
+}
diff --git a/test/CodeGenCXX/2010-03-09-AnonAggregate.cpp b/test/CodeGenCXX/2010-03-09-AnonAggregate.cpp
new file mode 100644
index 0000000..99883d8
--- /dev/null
+++ b/test/CodeGenCXX/2010-03-09-AnonAggregate.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -g -S -o %t %s
+// PR: 6554
+// More then one anonymous aggregates on one line creates chaos when MDNode uniquness is
+// combined with RAUW operation.
+// This test case causes crashes if malloc is configured to trip buffer overruns.
+class MO {
+
+ union { struct { union { int BA; } Val; int Offset; } OffsetedInfo; } Contents;
+
+};
+
+class MO m;
diff --git a/test/CodeGenCXX/PR6474.cpp b/test/CodeGenCXX/PR6474.cpp
new file mode 100644
index 0000000..68c09c9
--- /dev/null
+++ b/test/CodeGenCXX/PR6474.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 %s -emit-llvm
+
+namespace test0 {
+template <typename T> struct X {
+ virtual void foo();
+ virtual void bar();
+ virtual void baz();
+};
+
+template <typename T> void X<T>::foo() {}
+template <typename T> void X<T>::bar() {}
+template <typename T> void X<T>::baz() {}
+
+template <> void X<char>::foo() {}
+template <> void X<char>::bar() {}
+}
+
+namespace test1 {
+template <typename T> struct X {
+ virtual void foo();
+ virtual void bar();
+ virtual void baz();
+};
+
+template <typename T> void X<T>::foo() {}
+template <typename T> void X<T>::bar() {}
+template <typename T> void X<T>::baz() {}
+
+template <> void X<char>::bar() {}
+template <> void X<char>::foo() {}
+}
diff --git a/test/CodeGenCXX/default-destructor-nested.cpp b/test/CodeGenCXX/default-destructor-nested.cpp
new file mode 100644
index 0000000..8694274
--- /dev/null
+++ b/test/CodeGenCXX/default-destructor-nested.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 %s -emit-llvm-only
+// PR6294
+
+class A {
+ virtual ~A();
+};
+class B {
+ class C;
+};
+class B::C : public A {
+ C();
+};
+B::C::C() {}
diff --git a/test/CodeGenCXX/internal-linkage.cpp b/test/CodeGenCXX/internal-linkage.cpp
index 1ae0f08..4263891 100644
--- a/test/CodeGenCXX/internal-linkage.cpp
+++ b/test/CodeGenCXX/internal-linkage.cpp
@@ -1,11 +1,11 @@
// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
-struct Global { };
-template<typename T> struct X { };
+struct Global { Global(); };
+template<typename T> struct X { X(); };
namespace {
- struct Anon { };
+ struct Anon { Anon(); };
// CHECK: @_ZN12_GLOBAL__N_15anon0E = internal global
Global anon0;
diff --git a/test/CodeGenCXX/mangle-system-header.cpp b/test/CodeGenCXX/mangle-system-header.cpp
index cb68bc1..6716b58 100644
--- a/test/CodeGenCXX/mangle-system-header.cpp
+++ b/test/CodeGenCXX/mangle-system-header.cpp
@@ -5,3 +5,7 @@
# 1 "fake_system_header.h" 1 3 4
// CHECK: define void @_ZdlPvS_(
void operator delete (void*, void*) {}
+
+// PR6217
+// CHECK: define void @_Z3barv()
+void bar() { }
diff --git a/test/CodeGenCXX/nullptr.cpp b/test/CodeGenCXX/nullptr.cpp
index 31bd475..ab63b43 100644
--- a/test/CodeGenCXX/nullptr.cpp
+++ b/test/CodeGenCXX/nullptr.cpp
@@ -1,7 +1,17 @@
-// RUN: %clang_cc1 -std=c++0x %s -emit-llvm -o %t
+// RUN: %clang_cc1 -std=c++0x -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
int* a = nullptr;
void f() {
int* a = nullptr;
}
+
+typedef decltype(nullptr) nullptr_t;
+
+nullptr_t get_nullptr();
+
+struct X { };
+void g() {
+ // CHECK: call i8* @_Z11get_nullptrv()
+ int (X::*pmf)(int) = get_nullptr();
+}
diff --git a/test/CodeGenCXX/virtual-base-destructor-call.cpp b/test/CodeGenCXX/virtual-base-destructor-call.cpp
index b6e85e2..7de9dd2 100644
--- a/test/CodeGenCXX/virtual-base-destructor-call.cpp
+++ b/test/CodeGenCXX/virtual-base-destructor-call.cpp
@@ -22,6 +22,11 @@ int main() {
// CHECK: call void @_ZN14basic_iostreamIcED2Ev
// CHECK: call void @_ZN9basic_iosD2Ev
+// basic_iostream's base dtor calls its non-virtual base dtor.
+// CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED2Ev
+// CHECK: call void @_ZN13basic_istreamIcED2Ev
+// CHECK: }
+
// basic_iostream's deleting dtor calls its complete dtor, then
// operator delete().
// CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED0Ev
@@ -40,11 +45,6 @@ int main() {
// CHECK: call void @_ZN13basic_istreamIcED1Ev
// CHECK: call void @_ZdlPv
-// basic_iostream's base dtor calls its non-virtual base dtor.
-// CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED2Ev
-// CHECK: call void @_ZN13basic_istreamIcED2Ev
-// CHECK: }
-
// basic_istream's base dtor is a no-op.
// CHECK: define linkonce_odr void @_ZN13basic_istreamIcED2Ev
// CHECK-NOT: call
diff --git a/test/CodeGenCXX/vtable-layout-abi-examples.cpp b/test/CodeGenCXX/vtable-layout-abi-examples.cpp
index 2c6b7a4..a82fca7 100644
--- a/test/CodeGenCXX/vtable-layout-abi-examples.cpp
+++ b/test/CodeGenCXX/vtable-layout-abi-examples.cpp
@@ -187,3 +187,126 @@ struct D : public B, public C {
void D::d() { }
}
+
+namespace Test3 {
+
+// From http://www.codesourcery.com/public/cxx-abi/abi-examples.html#vtable-ctor
+
+struct V1 {
+ int v1;
+ virtual void f();
+};
+
+struct V2 : virtual V1 {
+ int v2;
+ virtual void f();
+};
+
+// CHECK: Vtable for 'Test3::C' (14 entries).
+// CHECK-NEXT: 0 | vbase_offset (32)
+// CHECK-NEXT: 1 | vbase_offset (16)
+// CHECK-NEXT: 2 | offset_to_top (0)
+// CHECK-NEXT: 3 | Test3::C RTTI
+// CHECK-NEXT: -- (Test3::C, 0) vtable address --
+// CHECK-NEXT: 4 | void Test3::C::f()
+// CHECK-NEXT: 5 | vcall_offset (-16)
+// CHECK-NEXT: 6 | offset_to_top (-16)
+// CHECK-NEXT: 7 | Test3::C RTTI
+// CHECK-NEXT: -- (Test3::V1, 16) vtable address --
+// CHECK-NEXT: 8 | void Test3::C::f()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT: 9 | vcall_offset (-32)
+// CHECK-NEXT: 10 | vbase_offset (-16)
+// CHECK-NEXT: 11 | offset_to_top (-32)
+// CHECK-NEXT: 12 | Test3::C RTTI
+// CHECK-NEXT: -- (Test3::V2, 32) vtable address --
+// CHECK-NEXT: 13 | void Test3::C::f()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
+
+// CHECK: Construction vtable for ('Test3::V2', 32) in 'Test3::C' (9 entries).
+// CHECK-NEXT: 0 | vcall_offset (0)
+// CHECK-NEXT: 1 | vbase_offset (-16)
+// CHECK-NEXT: 2 | offset_to_top (0)
+// CHECK-NEXT: 3 | Test3::V2 RTTI
+// CHECK-NEXT: -- (Test3::V2, 32) vtable address --
+// CHECK-NEXT: 4 | void Test3::V2::f()
+// CHECK-NEXT: 5 | vcall_offset (16)
+// CHECK-NEXT: 6 | offset_to_top (16)
+// CHECK-NEXT: 7 | Test3::V2 RTTI
+// CHECK-NEXT: -- (Test3::V1, 16) vtable address --
+// CHECK-NEXT: 8 | void Test3::V2::f()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+struct C : virtual V1, virtual V2 {
+ int c;
+ virtual void f();
+};
+void C::f() { }
+
+struct B {
+ int b;
+};
+
+// CHECK: Vtable for 'Test3::D' (15 entries).
+// CHECK-NEXT: 0 | vbase_offset (40)
+// CHECK-NEXT: 1 | vbase_offset (24)
+// CHECK-NEXT: 2 | offset_to_top (0)
+// CHECK-NEXT: 3 | Test3::D RTTI
+// CHECK-NEXT: -- (Test3::C, 0) vtable address --
+// CHECK-NEXT: -- (Test3::D, 0) vtable address --
+// CHECK-NEXT: 4 | void Test3::C::f()
+// CHECK-NEXT: 5 | void Test3::D::g()
+// CHECK-NEXT: 6 | vcall_offset (-24)
+// CHECK-NEXT: 7 | offset_to_top (-24)
+// CHECK-NEXT: 8 | Test3::D RTTI
+// CHECK-NEXT: -- (Test3::V1, 24) vtable address --
+// CHECK-NEXT: 9 | void Test3::C::f()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT: 10 | vcall_offset (-40)
+// CHECK-NEXT: 11 | vbase_offset (-16)
+// CHECK-NEXT: 12 | offset_to_top (-40)
+// CHECK-NEXT: 13 | Test3::D RTTI
+// CHECK-NEXT: -- (Test3::V2, 40) vtable address --
+// CHECK-NEXT: 14 | void Test3::C::f()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
+
+// CHECK: Construction vtable for ('Test3::C', 0) in 'Test3::D' (14 entries).
+// CHECK-NEXT: 0 | vbase_offset (40)
+// CHECK-NEXT: 1 | vbase_offset (24)
+// CHECK-NEXT: 2 | offset_to_top (0)
+// CHECK-NEXT: 3 | Test3::C RTTI
+// CHECK-NEXT: -- (Test3::C, 0) vtable address --
+// CHECK-NEXT: 4 | void Test3::C::f()
+// CHECK-NEXT: 5 | vcall_offset (-24)
+// CHECK-NEXT: 6 | offset_to_top (-24)
+// CHECK-NEXT: 7 | Test3::C RTTI
+// CHECK-NEXT: -- (Test3::V1, 24) vtable address --
+// CHECK-NEXT: 8 | void Test3::C::f()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT: 9 | vcall_offset (-40)
+// CHECK-NEXT: 10 | vbase_offset (-16)
+// CHECK-NEXT: 11 | offset_to_top (-40)
+// CHECK-NEXT: 12 | Test3::C RTTI
+// CHECK-NEXT: -- (Test3::V2, 40) vtable address --
+// CHECK-NEXT: 13 | void Test3::C::f()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
+
+// CHECK: Construction vtable for ('Test3::V2', 40) in 'Test3::D' (9 entries).
+// CHECK-NEXT: 0 | vcall_offset (0)
+// CHECK-NEXT: 1 | vbase_offset (-16)
+// CHECK-NEXT: 2 | offset_to_top (0)
+// CHECK-NEXT: 3 | Test3::V2 RTTI
+// CHECK-NEXT: -- (Test3::V2, 40) vtable address --
+// CHECK-NEXT: 4 | void Test3::V2::f()
+// CHECK-NEXT: 5 | vcall_offset (16)
+// CHECK-NEXT: 6 | offset_to_top (16)
+// CHECK-NEXT: 7 | Test3::V2 RTTI
+// CHECK-NEXT: -- (Test3::V1, 24) vtable address --
+// CHECK-NEXT: 8 | void Test3::V2::f()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+struct D : B, C {
+ int d;
+ virtual void g();
+};
+void D::g() { }
+
+}
diff --git a/test/CodeGenCXX/vtable-layout.cpp b/test/CodeGenCXX/vtable-layout.cpp
index a65af6e..5c783f1 100644
--- a/test/CodeGenCXX/vtable-layout.cpp
+++ b/test/CodeGenCXX/vtable-layout.cpp
@@ -1036,3 +1036,58 @@ struct C : A, virtual V, B {
void C::g() { }
}
+
+namespace Test26 {
+
+// Test that we generate the right number of entries in the C-in-D construction vtable, and that
+// we don't mark A::a as unused.
+
+struct A {
+ virtual void a();
+};
+
+struct B {
+ virtual void c();
+};
+
+struct C : virtual A {
+ virtual void b();
+};
+
+// CHECK: Vtable for 'Test26::D' (15 entries).
+// CHECK-NEXT: 0 | vbase_offset (8)
+// CHECK-NEXT: 1 | vbase_offset (8)
+// CHECK-NEXT: 2 | vbase_offset (0)
+// CHECK-NEXT: 3 | vcall_offset (0)
+// CHECK-NEXT: 4 | offset_to_top (0)
+// CHECK-NEXT: 5 | Test26::D RTTI
+// CHECK-NEXT: -- (Test26::B, 0) vtable address --
+// CHECK-NEXT: -- (Test26::D, 0) vtable address --
+// CHECK-NEXT: 6 | void Test26::B::c()
+// CHECK-NEXT: 7 | void Test26::D::d()
+// CHECK-NEXT: 8 | vcall_offset (0)
+// CHECK-NEXT: 9 | vbase_offset (0)
+// CHECK-NEXT: 10 | vcall_offset (0)
+// CHECK-NEXT: 11 | offset_to_top (-8)
+// CHECK-NEXT: 12 | Test26::D RTTI
+// CHECK-NEXT: -- (Test26::A, 8) vtable address --
+// CHECK-NEXT: -- (Test26::C, 8) vtable address --
+// CHECK-NEXT: 13 | void Test26::A::a()
+// CHECK-NEXT: 14 | void Test26::C::b()
+
+// CHECK: Construction vtable for ('Test26::C', 8) in 'Test26::D' (7 entries).
+// CHECK-NEXT: 0 | vcall_offset (0)
+// CHECK-NEXT: 1 | vbase_offset (0)
+// CHECK-NEXT: 2 | vcall_offset (0)
+// CHECK-NEXT: 3 | offset_to_top (0)
+// CHECK-NEXT: 4 | Test26::C RTTI
+// CHECK-NEXT: -- (Test26::A, 8) vtable address --
+// CHECK-NEXT: -- (Test26::C, 8) vtable address --
+// CHECK-NEXT: 5 | void Test26::A::a()
+// CHECK-NEXT: 6 | void Test26::C::b()
+class D : virtual B, virtual C {
+ virtual void d();
+};
+void D::d() { }
+
+}
diff --git a/test/CodeGenObjC/id-isa-codegen.m b/test/CodeGenObjC/id-isa-codegen.m
index e893aaa..e4f5fd9 100644
--- a/test/CodeGenObjC/id-isa-codegen.m
+++ b/test/CodeGenObjC/id-isa-codegen.m
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm -o - %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck -check-prefix LP64 %s
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -emit-llvm -o - %s | FileCheck -check-prefix LP32 %s
typedef struct objc_class *Class;
@@ -63,4 +64,10 @@ id Test2() {
((id)cat)->isa = dynamicSubclass;
}
@end
+// CHECK-LP64: %{{.*}} = load i8** %
+// CHECK-NEXT: %{{.*}} = bitcast i8* %{{.*}} to i8**
+// CHECK-NEXT: store i8* %{{.*}}, i8** %{{.*}}
+// CHECK-LP32: %{{.*}} = load i8** %
+// CHECK-NEXT: %{{.*}} = bitcast i8* %{{.*}} to i8**
+// CHECK-NEXT: store i8* %{{.*}}, i8** %{{.*}}
diff --git a/test/Driver/clang-g-opts.c b/test/Driver/clang-g-opts.c
new file mode 100644
index 0000000..4dbdf61
--- /dev/null
+++ b/test/Driver/clang-g-opts.c
@@ -0,0 +1,5 @@
+// RUN: %clang -S -v -o %t %s 2>&1 | not grep -w -- -g
+// RUN: %clang -S -v -o %t %s -g 2>&1 | grep -w -- -g
+// RUN: %clang -S -v -o %t %s -g0 2>&1 | not grep -w -- -g
+// RUN: %clang -S -v -o %t %s -g -g0 2>&1 | not grep -w -- -g
+// RUN: %clang -S -v -o %t %s -g0 -g 2>&1 | grep -w -- -g
diff --git a/test/FixIt/typo.cpp b/test/FixIt/typo.cpp
index c057025..efc9ba8 100644
--- a/test/FixIt/typo.cpp
+++ b/test/FixIt/typo.cpp
@@ -31,12 +31,12 @@ bool test_string(std::string s) {
std::basic_sting<char> b2; // expected-error{{no template named 'basic_sting' in namespace 'std'; did you mean 'basic_string'?}}
(void)b1;
(void)b2;
- return s.fnd("hello") // expected-error{{no member named 'fnd' in 'class std::basic_string<char>'; did you mean 'find'?}}
- == std::string::pos; // expected-error{{no member named 'pos' in 'class std::basic_string<char>'; did you mean 'npos'?}}
+ return s.fnd("hello") // expected-error{{no member named 'fnd' in 'std::basic_string<char>'; did you mean 'find'?}}
+ == std::string::pos; // expected-error{{no member named 'pos' in 'std::basic_string<char>'; did you mean 'npos'?}}
}
struct Base { };
-struct Derived : public Base { // expected-note{{base class 'struct Base' specified here}}
+struct Derived : public Base { // expected-note{{base class 'Base' specified here}}
int member; // expected-note 3{{'member' declared here}}
Derived() : base(), // expected-error{{initializer 'base' does not name a non-static data member or base class; did you mean the base class 'Base'?}}
diff --git a/test/Headers/typedef_guards.c b/test/Headers/typedef_guards.c
new file mode 100644
index 0000000..1aa667b
--- /dev/null
+++ b/test/Headers/typedef_guards.c
@@ -0,0 +1,28 @@
+// RUN: %clang -fsyntax-only -verify %s
+
+// NULL is rdefined in stddef.h
+#define NULL ((void*) 0)
+
+// These are headers bundled with Clang.
+#include <stdarg.h>
+#include <stddef.h>
+
+#ifndef _VA_LIST
+typedef __builtin_va_list va_list;
+#endif
+
+#ifndef _SIZE_T
+typedef __typeof__(sizeof(int)) size_t;
+#endif
+
+#ifndef _WCHAR_T
+typedef __typeof__(*L"") wchar_t;
+#endif
+
+extern void foo(wchar_t x);
+extern void bar(size_t x);
+void *baz() { return NULL; }
+void quz() {
+ va_list y;
+}
+
diff --git a/test/Index/annotate-tokens.m b/test/Index/annotate-tokens.m
new file mode 100644
index 0000000..1badeb2
--- /dev/null
+++ b/test/Index/annotate-tokens.m
@@ -0,0 +1,49 @@
+@interface Foo
+- (int)compare:(Foo*)other;
+@end
+
+@implementation Foo
+- (int)compare:(Foo*)other {
+ return 0;
+}
+@end
+
+// RUN: c-index-test -test-annotate-tokens=%s:1:1:9:5 %s | FileCheck %s
+// CHECK: Punctuation: "@" [1:1 - 1:2]
+// CHECK: Identifier: "interface" [1:2 - 1:11]
+// CHECK: Identifier: "Foo" [1:12 - 1:15] ObjCInterfaceDecl=Foo:1:12
+// CHECK: Punctuation: "-" [2:1 - 2:2] ObjCInstanceMethodDecl=compare::2:1
+// CHECK: Punctuation: "(" [2:3 - 2:4]
+// CHECK: Keyword: "int" [2:4 - 2:7]
+// CHECK: Punctuation: ")" [2:7 - 2:8]
+// CHECK: Identifier: "compare" [2:8 - 2:15]
+// CHECK: Punctuation: ":" [2:15 - 2:16]
+// CHECK: Punctuation: "(" [2:16 - 2:17]
+// CHECK: Identifier: "Foo" [2:17 - 2:20] ObjCClassRef=Foo:1:12
+// CHECK: Punctuation: "*" [2:20 - 2:21]
+// CHECK: Punctuation: ")" [2:21 - 2:22]
+// CHECK: Identifier: "other" [2:22 - 2:27] ParmDecl=other:2:22 (Definition)
+// CHECK: Punctuation: ";" [2:27 - 2:28]
+// CHECK: Punctuation: "@" [3:1 - 3:2]
+// CHECK: Identifier: "end" [3:2 - 3:5]
+// CHECK: Punctuation: "@" [5:1 - 5:2] ObjCImplementationDecl=Foo:5:1 (Definition)
+// CHECK: Identifier: "implementation" [5:2 - 5:16]
+// CHECK: Identifier: "Foo" [5:17 - 5:20]
+// CHECK: Punctuation: "-" [6:1 - 6:2] ObjCInstanceMethodDecl=compare::6:1 (Definition)
+// CHECK: Punctuation: "(" [6:3 - 6:4]
+// CHECK: Keyword: "int" [6:4 - 6:7]
+// CHECK: Punctuation: ")" [6:7 - 6:8]
+// CHECK: Identifier: "compare" [6:8 - 6:15]
+// CHECK: Punctuation: ":" [6:15 - 6:16]
+// CHECK: Punctuation: "(" [6:16 - 6:17]
+// CHECK: Identifier: "Foo" [6:17 - 6:20] ObjCClassRef=Foo:1:12
+// CHECK: Punctuation: "*" [6:20 - 6:21]
+// CHECK: Punctuation: ")" [6:21 - 6:22]
+// CHECK: Identifier: "other" [6:22 - 6:27] ParmDecl=other:6:22 (Definition)
+// CHECK: Punctuation: "{" [6:28 - 6:29]
+// CHECK: Keyword: "return" [7:3 - 7:9]
+// CHECK: Literal: "0" [7:10 - 7:11]
+// CHECK: Punctuation: ";" [7:11 - 7:12]
+// CHECK: Punctuation: "}" [8:1 - 8:2]
+// CHECK: Punctuation: "@" [9:1 - 9:2]
+// CHECK: Identifier: "end" [9:2 - 9:5]
diff --git a/test/Index/c-index-getCursor-test.m b/test/Index/c-index-getCursor-test.m
index 6a17e1c..8341b80 100644
--- a/test/Index/c-index-getCursor-test.m
+++ b/test/Index/c-index-getCursor-test.m
@@ -90,7 +90,9 @@ int main (int argc, const char * argv[]) {
// CHECK: [31:27 - 33:9] ObjCInterfaceDecl=Baz:31:12
// CHECK: [33:9 - 33:16] ObjCIvarDecl=_anIVar:33:9 (Definition)
// CHECK: [33:16 - 36:1] ObjCInterfaceDecl=Baz:31:12
-// CHECK: [36:1 - 36:21] ObjCInstanceMethodDecl=bazMethod:36:1
+// CHECK: [36:1 - 36:4] ObjCInstanceMethodDecl=bazMethod:36:1
+// CHECK: [36:4 - 36:7] ObjCClassRef=Foo:3:12
+// CHECK: [36:7 - 36:21] ObjCInstanceMethodDecl=bazMethod:36:1
// CHECK: [36:21 - 38:5] ObjCInterfaceDecl=Baz:31:12
// CHECK: [38:5 - 40:1] Invalid Cursor => NoDeclFound
// CHECK: [40:1 - 41:3] EnumDecl=:40:1 (Definition)
@@ -118,7 +120,9 @@ int main (int argc, const char * argv[]) {
// CHECK: [47:4 - 47:6] VarDecl=c:47:12 (Definition)
// CHECK: [47:6 - 47:10] ObjCProtocolRef=SubP:27:1
// CHECK: [47:10 - 47:16] VarDecl=c:47:12 (Definition)
-// CHECK: [47:16 - 47:26] ObjCMessageExpr=fooC:8:1
+// CHECK: [47:16 - 47:17] ObjCMessageExpr=fooC:8:1
+// CHECK: [47:17 - 47:20] ObjCClassRef=Foo:3:12
+// CHECK: [47:20 - 47:26] ObjCMessageExpr=fooC:8:1
// CHECK: [47:26 - 47:27] UnexposedStmt=
// CHECK: [47:27 - 48:2] UnexposedStmt=
// CHECK: [48:2 - 48:4] TypeRef=id:0:0
diff --git a/test/Index/code-completion.cpp b/test/Index/code-completion.cpp
index 7fd4376..670b13f 100644
--- a/test/Index/code-completion.cpp
+++ b/test/Index/code-completion.cpp
@@ -38,10 +38,10 @@ void test_overloaded() {
// CHECK-MEMBER: FieldDecl:{ResultType float}{Text Y::}{TypedText member}
// CHECK-MEMBER: FunctionDecl:{ResultType void}{Informative Y::}{TypedText memfunc}{LeftParen (}{Optional {Placeholder int i}}{RightParen )}
// CHECK-MEMBER: FunctionDecl:{ResultType int}{TypedText operator int}{LeftParen (}{RightParen )}{Informative const}
-// CHECK-MEMBER: FunctionDecl:{ResultType struct Z &}{TypedText operator=}{LeftParen (}{Placeholder struct Z const &}{RightParen )}
-// CHECK-MEMBER: FunctionDecl:{ResultType struct X &}{Text X::}{TypedText operator=}{LeftParen (}{Placeholder struct X const &}{RightParen )}
-// CHECK-MEMBER: FunctionDecl:{ResultType struct Y &}{Text Y::}{TypedText operator=}{LeftParen (}{Placeholder struct Y const &}{RightParen )}
-// CHECK-MEMBER: EnumConstantDecl:{ResultType enum X::E}{Informative E::}{TypedText Val1}
+// CHECK-MEMBER: FunctionDecl:{ResultType Z &}{TypedText operator=}{LeftParen (}{Placeholder Z const &}{RightParen )}
+// CHECK-MEMBER: FunctionDecl:{ResultType X &}{Text X::}{TypedText operator=}{LeftParen (}{Placeholder X const &}{RightParen )}
+// CHECK-MEMBER: FunctionDecl:{ResultType Y &}{Text Y::}{TypedText operator=}{LeftParen (}{Placeholder Y const &}{RightParen )}
+// CHECK-MEMBER: EnumConstantDecl:{ResultType X::E}{Informative E::}{TypedText Val1}
// CHECK-MEMBER: StructDecl:{TypedText X}{Text ::}
// CHECK-MEMBER: StructDecl:{TypedText Y}{Text ::}
// CHECK-MEMBER: StructDecl:{TypedText Z}{Text ::}
@@ -49,6 +49,6 @@ void test_overloaded() {
// CHECK-MEMBER: FunctionDecl:{ResultType void}{Informative Y::}{TypedText ~Y}{LeftParen (}{RightParen )}
// CHECK-MEMBER: FunctionDecl:{ResultType void}{TypedText ~Z}{LeftParen (}{RightParen )}
-// CHECK-OVERLOAD: NotImplemented:{ResultType int &}{Text overloaded}{LeftParen (}{Text struct Z z}{Comma , }{CurrentParameter int second}{RightParen )}
+// CHECK-OVERLOAD: NotImplemented:{ResultType int &}{Text overloaded}{LeftParen (}{Text Z z}{Comma , }{CurrentParameter int second}{RightParen )}
// CHECK-OVERLOAD: NotImplemented:{ResultType float &}{Text overloaded}{LeftParen (}{Text int i}{Comma , }{CurrentParameter long second}{RightParen )}
// CHECK-OVERLOAD: NotImplemented:{ResultType double &}{Text overloaded}{LeftParen (}{Text float f}{Comma , }{CurrentParameter int second}{RightParen )}
diff --git a/test/Parser/altivec.c b/test/Parser/altivec.c
index 99544ea..c2a32cf 100644
--- a/test/Parser/altivec.c
+++ b/test/Parser/altivec.c
@@ -41,28 +41,28 @@ void f_a(vector int a);
void f_a2(int b, vector int a);
// These should have warnings.
-__vector long vv_l; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-__vector signed long vv_sl; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-__vector unsigned long vv_ul; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-__vector long int vv_li; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-__vector signed long int vv_sli; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-__vector unsigned long int vv_uli; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-vector long v_l; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-vector signed long v_sl; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-vector unsigned long v_ul; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-vector long int v_li; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-vector signed long int v_sli; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-vector unsigned long int v_uli; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-__vector long double vv_ld; // expected-warning {{Use of "long" with "__vector" is deprecated}} expected-error {{cannot use "double" with "__vector"}}
-vector long double v_ld; // expected-warning {{Use of "long" with "__vector" is deprecated}} expected-error {{cannot use "double" with "__vector"}}
+__vector long vv_l; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector signed long vv_sl; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector unsigned long vv_ul; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector long int vv_li; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector signed long int vv_sli; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector unsigned long int vv_uli; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector long v_l; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector signed long v_sl; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector unsigned long v_ul; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector long int v_li; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector signed long int v_sli; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector unsigned long int v_uli; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector long double vv_ld; // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
+vector long double v_ld; // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
// These should have errors.
-__vector double vv_d; // expected-error {{cannot use "double" with "__vector"}}
-__vector double vv_d; // expected-error {{cannot use "double" with "__vector"}}
-vector double v_d; // expected-error {{cannot use "double" with "__vector"}}
-vector double v_d; // expected-error {{cannot use "double" with "__vector"}}
-__vector long double vv_ld; // expected-warning {{Use of "long" with "__vector" is deprecated}} expected-error {{cannot use "double" with "__vector"}}
-vector long double v_ld; // expected-warning {{Use of "long" with "__vector" is deprecated}} expected-error {{cannot use "double" with "__vector"}}
+__vector double vv_d; // expected-error {{cannot use 'double' with '__vector'}}
+__vector double vv_d; // expected-error {{cannot use 'double' with '__vector'}}
+vector double v_d; // expected-error {{cannot use 'double' with '__vector'}}
+vector double v_d; // expected-error {{cannot use 'double' with '__vector'}}
+__vector long double vv_ld; // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
+vector long double v_ld; // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
void f() {
__vector unsigned int v = {0,0,0,0};
diff --git a/test/Parser/cxx-altivec.cpp b/test/Parser/cxx-altivec.cpp
index a26eee4..3610c0e 100644
--- a/test/Parser/cxx-altivec.cpp
+++ b/test/Parser/cxx-altivec.cpp
@@ -43,26 +43,26 @@ void f_a(vector int a);
void f_a2(int b, vector int a);
// These should have warnings.
-__vector long vv_l; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-__vector signed long vv_sl; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-__vector unsigned long vv_ul; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-__vector long int vv_li; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-__vector signed long int vv_sli; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-__vector unsigned long int vv_uli; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-vector long v_l; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-vector signed long v_sl; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-vector unsigned long v_ul; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-vector long int v_li; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-vector signed long int v_sli; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-vector unsigned long int v_uli; // expected-warning {{Use of "long" with "__vector" is deprecated}}
-__vector long double vv_ld; // expected-warning {{Use of "long" with "__vector" is deprecated}} expected-error {{cannot use "double" with "__vector"}}
-vector long double v_ld; // expected-warning {{Use of "long" with "__vector" is deprecated}} expected-error {{cannot use "double" with "__vector"}}
+__vector long vv_l; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector signed long vv_sl; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector unsigned long vv_ul; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector long int vv_li; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector signed long int vv_sli; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector unsigned long int vv_uli; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector long v_l; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector signed long v_sl; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector unsigned long v_ul; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector long int v_li; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector signed long int v_sli; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+vector unsigned long int v_uli; // expected-warning {{Use of 'long' with '__vector' is deprecated}}
+__vector long double vv_ld; // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
+vector long double v_ld; // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
// These should have errors.
-__vector double vv_d1; // expected-error {{cannot use "double" with "__vector"}}
-vector double v_d2; // expected-error {{cannot use "double" with "__vector"}}
-__vector long double vv_ld3; // expected-warning {{Use of "long" with "__vector" is deprecated}} expected-error {{cannot use "double" with "__vector"}}
-vector long double v_ld4; // expected-warning {{Use of "long" with "__vector" is deprecated}} expected-error {{cannot use "double" with "__vector"}}
+__vector double vv_d1; // expected-error {{cannot use 'double' with '__vector'}}
+vector double v_d2; // expected-error {{cannot use 'double' with '__vector'}}
+__vector long double vv_ld3; // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
+vector long double v_ld4; // expected-warning {{Use of 'long' with '__vector' is deprecated}} expected-error {{cannot use 'double' with '__vector'}}
void f() {
__vector unsigned int v = {0,0,0,0};
diff --git a/test/Sema/warn-missing-braces.c b/test/Sema/warn-missing-braces.c
new file mode 100644
index 0000000..07eb61a
--- /dev/null
+++ b/test/Sema/warn-missing-braces.c
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -fsyntax-only -Wmissing-braces -verify %s
+
+int a[2][2] = { 0, 1, 2, 3 }; // expected-warning{{suggest braces}} expected-warning{{suggest braces}} \ No newline at end of file
diff --git a/test/SemaCXX/access-base-class.cpp b/test/SemaCXX/access-base-class.cpp
index d0b0fb8..eeb5f1c 100644
--- a/test/SemaCXX/access-base-class.cpp
+++ b/test/SemaCXX/access-base-class.cpp
@@ -5,7 +5,7 @@ class A { };
class B : private A { }; // expected-note {{declared private here}}
void f(B* b) {
- A *a = b; // expected-error{{cannot cast 'class T1::B' to its private base class 'class T1::A'}}
+ A *a = b; // expected-error{{cannot cast 'T1::B' to its private base class 'T1::A'}}
}
}
@@ -16,7 +16,7 @@ class A { };
class B : A { }; // expected-note {{implicitly declared private here}}
void f(B* b) {
- A *a = b; // expected-error {{cannot cast 'class T2::B' to its private base class 'class T2::A'}}
+ A *a = b; // expected-error {{cannot cast 'T2::B' to its private base class 'T2::A'}}
}
}
@@ -69,7 +69,7 @@ namespace T6 {
class C : public B {
void f(C *c) {
- A* a = c; // expected-error {{cannot cast 'class T6::C' to its private base class 'class T6::A'}}
+ A* a = c; // expected-error {{cannot cast 'T6::C' to its private base class 'T6::A'}}
}
};
diff --git a/test/SemaCXX/access-control-check.cpp b/test/SemaCXX/access-control-check.cpp
index 783d4de..1db6704 100644
--- a/test/SemaCXX/access-control-check.cpp
+++ b/test/SemaCXX/access-control-check.cpp
@@ -11,5 +11,5 @@ class P {
class N : M,P {
N() {}
- int PR() { return iP + PPR(); } // expected-error 2 {{private member of 'class P'}}
+ int PR() { return iP + PPR(); } // expected-error 2 {{private member of 'P'}}
};
diff --git a/test/SemaCXX/aggregate-initialization.cpp b/test/SemaCXX/aggregate-initialization.cpp
index 83f4179..708a8f2 100644
--- a/test/SemaCXX/aggregate-initialization.cpp
+++ b/test/SemaCXX/aggregate-initialization.cpp
@@ -22,10 +22,10 @@ struct NonAggr4 {
virtual void f();
};
-NonAggr1 na1 = { 17 }; // expected-error{{non-aggregate type 'struct NonAggr1' cannot be initialized with an initializer list}}
-NonAggr2 na2 = { 17 }; // expected-error{{non-aggregate type 'struct NonAggr2' cannot be initialized with an initializer list}}
-NonAggr3 na3 = { 17 }; // expected-error{{non-aggregate type 'class NonAggr3' cannot be initialized with an initializer list}}
-NonAggr4 na4 = { 17 }; // expected-error{{non-aggregate type 'struct NonAggr4' cannot be initialized with an initializer list}}
+NonAggr1 na1 = { 17 }; // expected-error{{non-aggregate type 'NonAggr1' cannot be initialized with an initializer list}}
+NonAggr2 na2 = { 17 }; // expected-error{{non-aggregate type 'NonAggr2' cannot be initialized with an initializer list}}
+NonAggr3 na3 = { 17 }; // expected-error{{non-aggregate type 'NonAggr3' cannot be initialized with an initializer list}}
+NonAggr4 na4 = { 17 }; // expected-error{{non-aggregate type 'NonAggr4' cannot be initialized with an initializer list}}
// PR5817
typedef int type[][2];
@@ -60,10 +60,10 @@ struct C {
void f() {
A as1[1] = { };
- A as2[1] = { 1 }; // expected-error {{copying array element of type 'struct A' invokes deleted copy constructor}}
+ A as2[1] = { 1 }; // expected-error {{copying array element of type 'A' invokes deleted copy constructor}}
B b1 = { };
- B b2 = { 1 }; // expected-error {{copying member subobject of type 'struct A' invokes deleted copy constructor}}
+ B b2 = { 1 }; // expected-error {{copying member subobject of type 'A' invokes deleted copy constructor}}
C c1 = { 1 };
}
diff --git a/test/SemaCXX/ambig-user-defined-conversions.cpp b/test/SemaCXX/ambig-user-defined-conversions.cpp
index 5e0a2e3..7f67674 100644
--- a/test/SemaCXX/ambig-user-defined-conversions.cpp
+++ b/test/SemaCXX/ambig-user-defined-conversions.cpp
@@ -19,7 +19,7 @@ namespace test0 {
const int Test1() {
func(b1, f()); // expected-error {{call to 'func' is ambiguous}}
- return f(); // expected-error {{conversion from 'struct test0::B' to 'int const' is ambiguous}}
+ return f(); // expected-error {{conversion from 'test0::B' to 'int const' is ambiguous}}
}
// This used to crash when comparing the two operands.
diff --git a/test/SemaCXX/arrow-operator.cpp b/test/SemaCXX/arrow-operator.cpp
index fd1ec01..29b23ed 100644
--- a/test/SemaCXX/arrow-operator.cpp
+++ b/test/SemaCXX/arrow-operator.cpp
@@ -16,7 +16,7 @@ struct C : A, B {
struct D : A { };
-struct E; // expected-note {{forward declaration of 'struct E'}}
+struct E; // expected-note {{forward declaration of 'E'}}
void f(C &c, D& d, E& e) {
c->f(); // expected-error{{use of overloaded operator '->' is ambiguous}}
diff --git a/test/SemaCXX/attr-cxx0x.cpp b/test/SemaCXX/attr-cxx0x.cpp
index 9924d1b..8fbf50c 100644
--- a/test/SemaCXX/attr-cxx0x.cpp
+++ b/test/SemaCXX/attr-cxx0x.cpp
@@ -2,7 +2,7 @@
int final_fail [[final]]; //expected-error {{'final' attribute only applies to virtual method or class types}}
-struct [[final]] final_base { }; // expected-note {{'struct final_base' declared here}}
+struct [[final]] final_base { }; // expected-note {{'final_base' declared here}}
struct final_child : final_base { }; // expected-error {{derivation from 'final' struct final_base}}
struct final_member { virtual void quux [[final]] (); }; // expected-note {{overridden virtual function is here}}
diff --git a/test/SemaCXX/builtin-ptrtomember-overload-1.cpp b/test/SemaCXX/builtin-ptrtomember-overload-1.cpp
index b1b0b98..f736394 100644
--- a/test/SemaCXX/builtin-ptrtomember-overload-1.cpp
+++ b/test/SemaCXX/builtin-ptrtomember-overload-1.cpp
@@ -41,6 +41,6 @@ void foo1(C1 c1, int A::* pmf) {
void foo1(C1 c1, int E::* pmf) {
int i = c1->*pmf; // expected-error {{use of overloaded operator '->*' is ambiguous}} \
- // expected-note {{because of ambiguity in conversion of 'struct C1' to 'struct E *'}} \
+ // expected-note {{because of ambiguity in conversion of 'C1' to 'E *'}} \
// expected-note 4 {{built-in candidate operator}}
}
diff --git a/test/SemaCXX/cast-conversion.cpp b/test/SemaCXX/cast-conversion.cpp
index 074e133..d68e789 100644
--- a/test/SemaCXX/cast-conversion.cpp
+++ b/test/SemaCXX/cast-conversion.cpp
@@ -13,9 +13,9 @@ struct B {
};
int main () {
- B(10); // expected-error {{functional-style cast from 'int' to 'struct B' is not allowed}}
- (B)10; // expected-error {{C-style cast from 'int' to 'struct B' is not allowed}}
- static_cast<B>(10); // expected-error {{static_cast from 'int' to 'struct B' is not allowed}} \\
+ B(10); // expected-error {{functional-style cast from 'int' to 'B' is not allowed}}
+ (B)10; // expected-error {{C-style cast from 'int' to 'B' is not allowed}}
+ static_cast<B>(10); // expected-error {{static_cast from 'int' to 'B' is not allowed}} \\
// expected-warning {{expression result unused}}
}
diff --git a/test/SemaCXX/class-base-member-init.cpp b/test/SemaCXX/class-base-member-init.cpp
index 67bc43c..1c6e790 100644
--- a/test/SemaCXX/class-base-member-init.cpp
+++ b/test/SemaCXX/class-base-member-init.cpp
@@ -8,7 +8,7 @@ public:
struct D : S {
D() : b1(0), b2(1), b1(0), S(), S() {} // expected-error {{multiple initializations given for non-static member 'b1'}} \
// expected-note {{previous initialization is here}} \
- // expected-error {{multiple initializations given for base 'class S'}} \
+ // expected-error {{multiple initializations given for base 'S'}} \
// expected-note {{previous initialization is here}}
int b1;
diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp
index b961ff2..4fcb0bb 100644
--- a/test/SemaCXX/conditional-expr.cpp
+++ b/test/SemaCXX/conditional-expr.cpp
@@ -85,7 +85,7 @@ void test()
// these are ambiguous
BadBase bb;
BadDerived bd;
- (void)(i1 ? bb : bd); // expected-error {{conditional expression is ambiguous; 'struct BadBase' can be converted to 'struct BadDerived' and vice versa}}
+ (void)(i1 ? bb : bd); // expected-error {{conditional expression is ambiguous; 'BadBase' can be converted to 'BadDerived' and vice versa}}
(void)(i1 ? bd : bb); // expected-error {{conditional expression is ambiguous}}
// curiously enough (and a defect?), these are not
// for rvalues, hierarchy takes precedence over other conversions
@@ -106,19 +106,19 @@ void test()
i1 = (i1 ? Base() : Derived()).trick();
i1 = (i1 ? Derived() : Base()).trick();
// should fail: const lost
- (void)(i1 ? Base() : constder()); // expected-error {{incompatible operand types ('struct Base' and 'struct Derived const')}}
- (void)(i1 ? constder() : Base()); // expected-error {{incompatible operand types ('struct Derived const' and 'struct Base')}}
+ (void)(i1 ? Base() : constder()); // expected-error {{incompatible operand types ('Base' and 'Derived const')}}
+ (void)(i1 ? constder() : Base()); // expected-error {{incompatible operand types ('Derived const' and 'Base')}}
Priv priv;
Fin fin;
(void)(i1 ? Base() : Priv()); // expected-error{{private base class}}
(void)(i1 ? Priv() : Base()); // expected-error{{private base class}}
- (void)(i1 ? Base() : Fin()); // expected-error{{ambiguous conversion from derived class 'struct Fin' to base class 'struct Base'}}
- (void)(i1 ? Fin() : Base()); // expected-error{{ambiguous conversion from derived class 'struct Fin' to base class 'struct Base'}}
+ (void)(i1 ? Base() : Fin()); // expected-error{{ambiguous conversion from derived class 'Fin' to base class 'Base':}}
+ (void)(i1 ? Fin() : Base()); // expected-error{{ambiguous conversion from derived class 'Fin' to base class 'Base':}}
(void)(i1 ? base : priv); // expected-error {{private base class}}
(void)(i1 ? priv : base); // expected-error {{private base class}}
- (void)(i1 ? base : fin); // expected-error {{ambiguous conversion from derived class 'struct Fin' to base class 'struct Base'}}
- (void)(i1 ? fin : base); // expected-error {{ambiguous conversion from derived class 'struct Fin' to base class 'struct Base'}}
+ (void)(i1 ? base : fin); // expected-error {{ambiguous conversion from derived class 'Fin' to base class 'Base':}}
+ (void)(i1 ? fin : base); // expected-error {{ambiguous conversion from derived class 'Fin' to base class 'Base':}}
// b2.2 (non-hierarchy)
i1 = i1 ? I() : i1;
@@ -128,10 +128,10 @@ void test()
// "the type [it] woud have if E2 were converted to an rvalue"
vfn pfn = i1 ? F() : test;
pfn = i1 ? test : F();
- (void)(i1 ? A() : B()); // expected-error {{conversion from 'struct B' to 'struct A' is ambiguous}}
- (void)(i1 ? B() : A()); // expected-error {{conversion from 'struct B' to 'struct A' is ambiguous}}
- (void)(i1 ? 1 : Ambig()); // expected-error {{conversion from 'struct Ambig' to 'int' is ambiguous}}
- (void)(i1 ? Ambig() : 1); // expected-error {{conversion from 'struct Ambig' to 'int' is ambiguous}}
+ (void)(i1 ? A() : B()); // expected-error {{conversion from 'B' to 'A' is ambiguous}}
+ (void)(i1 ? B() : A()); // expected-error {{conversion from 'B' to 'A' is ambiguous}}
+ (void)(i1 ? 1 : Ambig()); // expected-error {{conversion from 'Ambig' to 'int' is ambiguous}}
+ (void)(i1 ? Ambig() : 1); // expected-error {{conversion from 'Ambig' to 'int' is ambiguous}}
// By the way, this isn't an lvalue:
&(i1 ? i1 : i2); // expected-error {{address expression must be an lvalue or a function designator}}
diff --git a/test/SemaCXX/const-cast.cpp b/test/SemaCXX/const-cast.cpp
index 220e6fa..50bd316 100644
--- a/test/SemaCXX/const-cast.cpp
+++ b/test/SemaCXX/const-cast.cpp
@@ -59,6 +59,6 @@ short *bad_const_cast_test(char const *volatile *const volatile *var)
// Function pointers.
f fp2 = const_cast<f>(fp1); // expected-error {{const_cast to 'f' (aka 'int (*)(int)'), which is not a reference, pointer-to-object, or pointer-to-data-member}}
void (A::*mfn)() = 0;
- (void)const_cast<void (A::*)()>(mfn); // expected-error {{const_cast to 'void (struct A::*)()', which is not a reference, pointer-to-object, or pointer-to-data-member}}
+ (void)const_cast<void (A::*)()>(mfn); // expected-error {{const_cast to 'void (A::*)()', which is not a reference, pointer-to-object, or pointer-to-data-member}}
return **var3;
}
diff --git a/test/SemaCXX/constructor-initializer.cpp b/test/SemaCXX/constructor-initializer.cpp
index 2efb7b9..96dfa8b 100644
--- a/test/SemaCXX/constructor-initializer.cpp
+++ b/test/SemaCXX/constructor-initializer.cpp
@@ -27,7 +27,7 @@ public:
class E : public D, public B {
public:
- E() : B(), D() { } // expected-error{{base class initializer 'class B' names both a direct base class and an inherited virtual base class}}
+ E() : B(), D() { } // expected-error{{base class initializer 'B' names both a direct base class and an inherited virtual base class}}
};
@@ -65,7 +65,7 @@ struct S : Y, virtual X {
};
struct Z : S {
- Z() : X(), S(), E() {} // expected-error {{type 'class E' is not a direct or virtual base of 'Z'}}
+ Z() : X(), S(), E() {} // expected-error {{type 'E' is not a direct or virtual base of 'Z'}}
};
class U {
@@ -104,13 +104,13 @@ struct M { // expected-note 2 {{candidate constructor (the implicit
};
struct N : M {
- N() : M(1), // expected-error {{no matching constructor for initialization of 'struct M'}}
- m1(100) { } // expected-error {{no matching constructor for initialization of 'struct M'}}
+ N() : M(1), // expected-error {{no matching constructor for initialization of 'M'}}
+ m1(100) { } // expected-error {{no matching constructor for initialization of 'M'}}
M m1;
};
struct P : M {
- P() { } // expected-error {{base class 'struct M'}} \
+ P() { } // expected-error {{constructor for 'P' must explicitly initialize the base class 'M' which does not have a default constructor}} \
// expected-error {{member 'm'}}
M m; // expected-note {{member is declared here}}
};
diff --git a/test/SemaCXX/conversion-delete-expr.cpp b/test/SemaCXX/conversion-delete-expr.cpp
index 2338778..862ae5a 100644
--- a/test/SemaCXX/conversion-delete-expr.cpp
+++ b/test/SemaCXX/conversion-delete-expr.cpp
@@ -11,7 +11,7 @@ struct D : B {
void f (D d)
{
- delete d; // expected-error {{ambiguous conversion of delete expression of type 'struct D' to a pointer}}
+ delete d; // expected-error {{ambiguous conversion of delete expression of type 'D' to a pointer}}
}
// Test2
@@ -39,7 +39,7 @@ struct D2 : B2 {
void f2 (D2 d)
{
- delete d; // expected-error {{ambiguous conversion of delete expression of type 'struct D2' to a pointer}}
+ delete d; // expected-error {{ambiguous conversion of delete expression of type 'D2' to a pointer}}
}
// Test4
@@ -56,7 +56,7 @@ struct D3 : A3, B3 {
void f3 (D3 d)
{
- delete d; // expected-error {{mbiguous conversion of delete expression of type 'struct D3' to a pointer}}
+ delete d; // expected-error {{ambiguous conversion of delete expression of type 'D3' to a pointer}}
}
// Test5
diff --git a/test/SemaCXX/conversion-function.cpp b/test/SemaCXX/conversion-function.cpp
index 4fef172..bca75c0 100644
--- a/test/SemaCXX/conversion-function.cpp
+++ b/test/SemaCXX/conversion-function.cpp
@@ -49,9 +49,9 @@ class A { };
class B : public A {
public:
- operator A&() const; // expected-warning{{conversion function converting 'class B' to its base class 'class A' will never be used}}
- operator const void() const; // expected-warning{{conversion function converting 'class B' to 'void const' will never be used}}
- operator const B(); // expected-warning{{conversion function converting 'class B' to itself will never be used}}
+ operator A&() const; // expected-warning{{conversion function converting 'B' to its base class 'A' will never be used}}
+ operator const void() const; // expected-warning{{conversion function converting 'B' to 'void const' will never be used}}
+ operator const B(); // expected-warning{{conversion function converting 'B' to itself will never be used}}
};
// This used to crash Clang.
@@ -63,7 +63,7 @@ struct Flop { // expected-note{{candidate is the implicit copy constructor}}
struct Flip {
operator Flop() const; // expected-note{{candidate function}}
};
-Flop flop = Flip(); // expected-error {{conversion from 'struct Flip' to 'struct Flop' is ambiguous}}
+Flop flop = Flip(); // expected-error {{conversion from 'Flip' to 'Flop' is ambiguous}}
// This tests that we don't add the second conversion declaration to the list of user conversions
struct C {
@@ -88,7 +88,7 @@ public:
};
void f(Yb& a) {
- if (a) { } // expected-error {{conversion from 'class Yb' to 'bool' is ambiguous}}
+ if (a) { } // expected-error {{conversion from 'Yb' to 'bool' is ambiguous}}
int i = a; // OK. calls XB::operator int();
char ch = a; // OK. calls Yb::operator char();
}
diff --git a/test/SemaCXX/convert-to-bool.cpp b/test/SemaCXX/convert-to-bool.cpp
index 4b5002e..4cd22e9 100644
--- a/test/SemaCXX/convert-to-bool.cpp
+++ b/test/SemaCXX/convert-to-bool.cpp
@@ -44,12 +44,12 @@ struct ExplicitConvToRef {
void test_explicit_bool(ExplicitConvToBool ecb) {
bool b1(ecb); // okay
- bool b2 = ecb; // expected-error{{no viable conversion from 'struct ExplicitConvToBool' to 'bool'}}
+ bool b2 = ecb; // expected-error{{no viable conversion from 'ExplicitConvToBool' to 'bool'}}
accepts_bool(ecb); // expected-error{{no matching function for call to}}
}
void test_explicit_conv_to_ref(ExplicitConvToRef ecr) {
- int& i1 = ecr; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a value of unrelated type 'struct ExplicitConvToRef'}}
+ int& i1 = ecr; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a value of unrelated type 'ExplicitConvToRef'}}
int& i2(ecr); // okay
}
@@ -61,7 +61,7 @@ struct C {
};
void test_copy_init_conversions(C c) {
- A &a = c; // expected-error{{no viable conversion from 'struct C' to 'struct A'}}
+ A &a = c; // expected-error{{no viable conversion from 'C' to 'A'}}
B &b = b; // okay
}
diff --git a/test/SemaCXX/copy-assignment.cpp b/test/SemaCXX/copy-assignment.cpp
index d7eb5cf..8cdb1be 100644
--- a/test/SemaCXX/copy-assignment.cpp
+++ b/test/SemaCXX/copy-assignment.cpp
@@ -94,6 +94,6 @@ void test() {
int i;
i = convertibleToInt;
- i = a; // expected-error{{incompatible type assigning 'struct A', expected 'int'}}
+ i = a; // expected-error{{incompatible type assigning 'A', expected 'int'}}
}
diff --git a/test/SemaCXX/copy-initialization.cpp b/test/SemaCXX/copy-initialization.cpp
index 2cf878a..3a63be0 100644
--- a/test/SemaCXX/copy-initialization.cpp
+++ b/test/SemaCXX/copy-initialization.cpp
@@ -9,7 +9,7 @@ public:
class Y : public X { };
void f(Y y, int *ip, float *fp) {
- X x1 = y; // expected-error{{no matching constructor for initialization of 'class X'}}
+ X x1 = y; // expected-error{{no matching constructor for initialization of 'X'}}
X x2 = 0;
X x3 = ip;
X x4 = fp; // expected-error{{no viable conversion}}
@@ -20,4 +20,4 @@ struct foo {
};
// PR3600
-void test(const foo *P) { P->bar(); } // expected-error{{cannot initialize object parameter of type 'struct foo' with an expression of type 'struct foo const'}}
+void test(const foo *P) { P->bar(); } // expected-error{{cannot initialize object parameter of type 'foo' with an expression of type 'foo const'}}
diff --git a/test/SemaCXX/cstyle-cast.cpp b/test/SemaCXX/cstyle-cast.cpp
index dbb1e4a..6a28f4c 100644
--- a/test/SemaCXX/cstyle-cast.cpp
+++ b/test/SemaCXX/cstyle-cast.cpp
@@ -122,12 +122,12 @@ void t_529_5_8()
// Bad code below
- (void)(C1*)((A*)0); // expected-error {{cannot cast 'struct A *' to 'struct C1 *' via virtual base 'struct B'}}
- (void)(C1&)(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct C1 &' via virtual base 'struct B'}}
- (void)(D*)((A*)0); // expected-error {{cannot cast 'struct A *' to 'struct D *' via virtual base 'struct B'}}
- (void)(D&)(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct D &' via virtual base 'struct B'}}
- (void)(H*)((A*)0); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
- (void)(H&)(*((A*)0)); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
+ (void)(C1*)((A*)0); // expected-error {{cannot cast 'A *' to 'C1 *' via virtual base 'B'}}
+ (void)(C1&)(*((A*)0)); // expected-error {{cannot cast 'A' to 'C1 &' via virtual base 'B'}}
+ (void)(D*)((A*)0); // expected-error {{cannot cast 'A *' to 'D *' via virtual base 'B'}}
+ (void)(D&)(*((A*)0)); // expected-error {{cannot cast 'A' to 'D &' via virtual base 'B'}}
+ (void)(H*)((A*)0); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
+ (void)(H&)(*((A*)0)); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
// TODO: Test DR427. This requires user-defined conversions, though.
}
@@ -141,7 +141,7 @@ void t_529_7()
// Bad code below
- (void)(Enum)((int*)0); // expected-error {{C-style cast from 'int *' to 'enum Enum' is not allowed}}
+ (void)(Enum)((int*)0); // expected-error {{C-style cast from 'int *' to 'Enum' is not allowed}}
}
// Void pointer to object pointer
@@ -158,8 +158,8 @@ void t_529_9()
(void)(int A::*)((int B::*)0);
// Bad code below
- (void)(int A::*)((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'struct H'}}
- (void)(int A::*)((int F::*)0); // expected-error {{conversion from pointer to member of class 'struct F'}}
+ (void)(int A::*)((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'H' to pointer to member of base class 'A':}}
+ (void)(int A::*)((int F::*)0); // expected-error {{conversion from pointer to member of class 'F' to pointer to member of class 'A' via virtual base 'B' is not allowed}}
}
// -------- reinterpret_cast -----------
@@ -226,6 +226,6 @@ void memptrs()
void (structure::*psf)() = 0;
(void)(int (structure::*)())(psf);
- (void)(void (structure::*)())(psi); // expected-error {{C-style cast from 'int const struct structure::*' to 'void (struct structure::*)()' is not allowed}}
- (void)(int structure::*)(psf); // expected-error {{C-style cast from 'void (struct structure::*)()' to 'int struct structure::*' is not allowed}}
+ (void)(void (structure::*)())(psi); // expected-error {{C-style cast from 'int const structure::*' to 'void (structure::*)()' is not allowed}}
+ (void)(int structure::*)(psf); // expected-error {{C-style cast from 'void (structure::*)()' to 'int structure::*' is not allowed}}
}
diff --git a/test/SemaCXX/dcl_init_aggr.cpp b/test/SemaCXX/dcl_init_aggr.cpp
index 461c60b..8b28663 100644
--- a/test/SemaCXX/dcl_init_aggr.cpp
+++ b/test/SemaCXX/dcl_init_aggr.cpp
@@ -13,9 +13,9 @@ struct NonAggregate {
int a, b;
};
-NonAggregate non_aggregate_test = { 1, 2 }; // expected-error{{non-aggregate type 'struct NonAggregate' cannot be initialized with an initializer list}}
+NonAggregate non_aggregate_test = { 1, 2 }; // expected-error{{non-aggregate type 'NonAggregate' cannot be initialized with an initializer list}}
-NonAggregate non_aggregate_test2[2] = { { 1, 2 }, { 3, 4 } }; // expected-error 2 {{initialization of non-aggregate type 'struct NonAggregate' with an initializer list}}
+NonAggregate non_aggregate_test2[2] = { { 1, 2 }, { 3, 4 } }; // expected-error 2 {{initialization of non-aggregate type 'NonAggregate' with an initializer list}}
// C++ [dcl.init.aggr]p3
@@ -51,7 +51,7 @@ struct TooFewError { // expected-error{{implicit default constructor for}}
TooFewError too_few_okay = { 1, 1 };
TooFewError too_few_error = { 1 }; // expected-error{{no matching constructor}}
-TooFewError too_few_okay2[2] = { 1, 1 }; // expected-note{{implicit default constructor for 'struct TooFewError' first required here}}
+TooFewError too_few_okay2[2] = { 1, 1 }; // expected-note{{implicit default constructor for 'TooFewError' first required here}}
TooFewError too_few_error2[2] = { 1 }; // expected-error{{no matching constructor}}
NoDefaultConstructor too_few_error3[3] = { }; // expected-error {{no matching constructor}}
diff --git a/test/SemaCXX/decl-init-ref.cpp b/test/SemaCXX/decl-init-ref.cpp
index 2f7d8a4..7ae0439 100644
--- a/test/SemaCXX/decl-init-ref.cpp
+++ b/test/SemaCXX/decl-init-ref.cpp
@@ -21,9 +21,9 @@ extern B f();
const int& ri = (void)0; // expected-error {{reference to type 'int const' could not bind to an rvalue of type 'void'}}
int main() {
- const A& rca = f(); // expected-error {{reference initialization of type 'struct A const &' with initializer of type 'class B' is ambiguous}}
- A& ra = f(); // expected-error {{non-const lvalue reference to type 'struct A' cannot bind to a temporary of type 'class B'}}
+ const A& rca = f(); // expected-error {{reference initialization of type 'A const &' with initializer of type 'B' is ambiguous}}
+ A& ra = f(); // expected-error {{non-const lvalue reference to type 'A' cannot bind to a temporary of type 'B'}}
}
struct PR6139 { A (&x)[1]; };
-PR6139 x = {{A()}}; // expected-error{{non-const lvalue reference to type 'struct A [1]' cannot bind to a temporary of type 'struct A'}}
+PR6139 x = {{A()}}; // expected-error{{non-const lvalue reference to type 'A [1]' cannot bind to a temporary of type 'A'}}
diff --git a/test/SemaCXX/decltype-overloaded-functions.cpp b/test/SemaCXX/decltype-overloaded-functions.cpp
index 906e868..0aa49b0 100644
--- a/test/SemaCXX/decltype-overloaded-functions.cpp
+++ b/test/SemaCXX/decltype-overloaded-functions.cpp
@@ -9,4 +9,4 @@ template<typename T> struct S {
};
struct K { void f(); void f(int); };
-S<K> b; // expected-note{{in instantiation of template class 'struct S<struct K>' requested here}}
+S<K> b; // expected-note{{in instantiation of template class 'S<K>' requested here}}
diff --git a/test/SemaCXX/default-assignment-operator.cpp b/test/SemaCXX/default-assignment-operator.cpp
index 9c99ad5..baae03c 100644
--- a/test/SemaCXX/default-assignment-operator.cpp
+++ b/test/SemaCXX/default-assignment-operator.cpp
@@ -1,10 +1,10 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-class Base { // expected-error {{cannot define the implicit default assignment operator for 'class Base'}}
+class Base { // expected-error {{cannot define the implicit default assignment operator for 'Base', because non-static reference member 'ref' can't use default assignment operator}}
int &ref; // expected-note {{declared at}}
};
-class X : Base { // // expected-error {{cannot define the implicit default assignment operator for 'class X'}}
+class X : Base { // // expected-error {{cannot define the implicit default assignment operator for 'X', because non-static const member 'cint' can't use default assignment operator}}
public:
X();
const int cint; // expected-note {{declared at}}
@@ -70,7 +70,7 @@ void i() {
// Test5
-class E1 { // expected-error{{cannot define the implicit default assignment operator for 'class E1', because non-static const member 'a' can't use default assignment operator}}
+class E1 { // expected-error{{cannot define the implicit default assignment operator for 'E1', because non-static const member 'a' can't use default assignment operator}}
public:
const int a; // expected-note{{declared at}}
E1() : a(0) {}
diff --git a/test/SemaCXX/default-constructor-initializers.cpp b/test/SemaCXX/default-constructor-initializers.cpp
index 4269991..b40b133 100644
--- a/test/SemaCXX/default-constructor-initializers.cpp
+++ b/test/SemaCXX/default-constructor-initializers.cpp
@@ -4,12 +4,11 @@ struct X1 { // has no implicit default constructor
X1(int);
};
-struct X2 : X1 { // expected-note {{'struct X2' declared here}} \
- // expected-note {{'struct X2' declared here}}
+struct X2 : X1 { // expected-note 2 {{'X2' declared here}}
X2(int);
};
-struct X3 : public X2 { // expected-error {{must explicitly initialize the base class 'struct X2'}}
+struct X3 : public X2 { // expected-error {{implicit default constructor for 'X3' must explicitly initialize the base class 'X2' which does not have a default constructor}}
};
X3 x3; // expected-note {{first required here}}
diff --git a/test/SemaCXX/default2.cpp b/test/SemaCXX/default2.cpp
index e674260..a0999c0 100644
--- a/test/SemaCXX/default2.cpp
+++ b/test/SemaCXX/default2.cpp
@@ -91,12 +91,12 @@ public:
}
void test_Z(const Z& z) {
- Z z2(z); // expected-error{{no matching constructor for initialization of 'class Z'}}
+ Z z2(z); // expected-error{{no matching constructor for initialization of 'Z'}}
}
};
void test_Z(const Z& z) {
- Z z2(z); // expected-error{{no matching constructor for initialization of 'class Z'}}
+ Z z2(z); // expected-error{{no matching constructor for initialization of 'Z'}}
}
struct ZZ {
diff --git a/test/SemaCXX/deleted-function.cpp b/test/SemaCXX/deleted-function.cpp
index d9df1bf..b3e1296 100644
--- a/test/SemaCXX/deleted-function.cpp
+++ b/test/SemaCXX/deleted-function.cpp
@@ -29,7 +29,7 @@ void test() {
ov(1);
ov(1.0); // expected-error {{call to deleted function 'ov'}}
- WithDel dd; // expected-error {{call to deleted constructor of 'struct WithDel'}}
+ WithDel dd; // expected-error {{call to deleted constructor of 'WithDel'}}
WithDel *d = 0;
d->fn(); // expected-error {{attempt to use a deleted function}}
int i = *d; // expected-error {{invokes a deleted function}}
diff --git a/test/SemaCXX/derived-to-base-ambig.cpp b/test/SemaCXX/derived-to-base-ambig.cpp
index cfcad79..9216e5b 100644
--- a/test/SemaCXX/derived-to-base-ambig.cpp
+++ b/test/SemaCXX/derived-to-base-ambig.cpp
@@ -6,7 +6,7 @@ class D : public B, public C { };
void f(D* d) {
A* a;
- a = d; // expected-error{{ambiguous conversion from derived class 'class D' to base class 'class A'}} expected-error{{incompatible type assigning 'class D *', expected 'class A *'}}
+ a = d; // expected-error{{ambiguous conversion from derived class 'D' to base class 'A':}} expected-error{{incompatible type assigning 'D *', expected 'A *'}}
}
class Object2 { };
@@ -20,7 +20,7 @@ class F2 : public E2, public A2 { };
void g(E2* e2, F2* f2) {
Object2* o2;
o2 = e2;
- o2 = f2; // expected-error{{ambiguous conversion from derived class 'class F2' to base class 'class Object2'}} expected-error{{incompatible type assigning 'class F2 *', expected 'class Object2 *'}}
+ o2 = f2; // expected-error{{ambiguous conversion from derived class 'F2' to base class 'Object2':}} expected-error{{incompatible type assigning 'F2 *', expected 'Object2 *'}}
}
// Test that ambiguous/inaccessibility checking does not trigger too
diff --git a/test/SemaCXX/destructor.cpp b/test/SemaCXX/destructor.cpp
index ab3c809..7010d2e 100644
--- a/test/SemaCXX/destructor.cpp
+++ b/test/SemaCXX/destructor.cpp
@@ -32,7 +32,7 @@ struct E;
typedef E E_typedef;
struct E {
- ~E_typedef(); // expected-error{{destructor cannot be declared using a typedef 'E_typedef' (aka 'struct E') of the class name}}
+ ~E_typedef(); // expected-error{{destructor cannot be declared using a typedef 'E_typedef' (aka 'E') of the class name}}
};
struct F {
diff --git a/test/SemaCXX/direct-initializer.cpp b/test/SemaCXX/direct-initializer.cpp
index 6601a3d..d30642b 100644
--- a/test/SemaCXX/direct-initializer.cpp
+++ b/test/SemaCXX/direct-initializer.cpp
@@ -28,11 +28,11 @@ public:
void g() {
X x1(5);
X x2(1.0, 3, 4.2);
- X x3(1.0, 1.0); // expected-error{{no matching constructor for initialization of 'class X'}}
+ X x3(1.0, 1.0); // expected-error{{no matching constructor for initialization of 'X'}}
Y y(1.0);
X x4(3.14, y);
- Z z; // expected-error{{no matching constructor for initialization of 'class Z'}}
+ Z z; // expected-error{{no matching constructor for initialization of 'Z'}}
}
struct Base {
@@ -44,7 +44,7 @@ struct Derived : Base {
};
void foo(const Derived cd, Derived d) {
- int *pi = cd; // expected-error {{no viable conversion from 'struct Derived const' to 'int *'}}
+ int *pi = cd; // expected-error {{no viable conversion from 'Derived const' to 'int *'}}
int *ppi = d;
}
diff --git a/test/SemaCXX/dynamic-cast.cpp b/test/SemaCXX/dynamic-cast.cpp
index 53d0b9d..b73e8c5 100644
--- a/test/SemaCXX/dynamic-cast.cpp
+++ b/test/SemaCXX/dynamic-cast.cpp
@@ -8,7 +8,7 @@ struct D : private A {};
struct E : A {};
struct F : B, E {};
-struct Incomplete; // expected-note 2 {{forward declaration of 'struct Incomplete'}}
+struct Incomplete; // expected-note 2 {{forward declaration of 'Incomplete'}}
struct Poly
{
@@ -22,7 +22,7 @@ struct PolyDerived : Poly
void basic_bad()
{
// ptr -> nonptr
- (void)dynamic_cast<A>((A*)0); // expected-error {{'struct A' is not a reference or pointer}}
+ (void)dynamic_cast<A>((A*)0); // expected-error {{'A' is not a reference or pointer}}
// nonptr -> ptr
(void)dynamic_cast<A*>(0); // expected-error {{'int' is not a pointer}}
// ptr -> noncls
@@ -34,9 +34,9 @@ void basic_bad()
// noncls -> ref
(void)dynamic_cast<A&>(*((int*)0)); // expected-error {{'int' is not a class}}
// ptr -> incomplete
- (void)dynamic_cast<Incomplete*>((A*)0); // expected-error {{'struct Incomplete' is an incomplete type}}
+ (void)dynamic_cast<Incomplete*>((A*)0); // expected-error {{'Incomplete' is an incomplete type}}
// incomplete -> ptr
- (void)dynamic_cast<A*>((Incomplete*)0); // expected-error {{'struct Incomplete' is an incomplete type}}
+ (void)dynamic_cast<A*>((Incomplete*)0); // expected-error {{'Incomplete' is an incomplete type}}
}
void same()
@@ -57,8 +57,8 @@ void up()
//(void)dynamic_cast<A&>(*((D*)0));
// Ambiguous
- (void)dynamic_cast<A*>((F*)0); // expected-error {{ambiguous conversion from derived class 'struct F' to base class 'struct A':\n struct F -> struct B -> struct A\n struct F -> struct E -> struct A}}
- (void)dynamic_cast<A&>(*((F*)0)); // expected-error {{ambiguous conversion from derived class 'struct F' to base class 'struct A':\n struct F -> struct B -> struct A\n struct F -> struct E -> struct A}}
+ (void)dynamic_cast<A*>((F*)0); // expected-error {{ambiguous conversion from derived class 'F' to base class 'A':\n struct F -> struct B -> struct A\n struct F -> struct E -> struct A}}
+ (void)dynamic_cast<A&>(*((F*)0)); // expected-error {{ambiguous conversion from derived class 'F' to base class 'A':\n struct F -> struct B -> struct A\n struct F -> struct E -> struct A}}
}
void poly()
@@ -69,6 +69,6 @@ void poly()
(void)dynamic_cast<A&>(*((PolyDerived*)0));
// Not polymorphic source
- (void)dynamic_cast<Poly*>((A*)0); // expected-error {{'struct A' is not polymorphic}}
- (void)dynamic_cast<PolyDerived&>(*((A*)0)); // expected-error {{'struct A' is not polymorphic}}
+ (void)dynamic_cast<Poly*>((A*)0); // expected-error {{'A' is not polymorphic}}
+ (void)dynamic_cast<PolyDerived&>(*((A*)0)); // expected-error {{'A' is not polymorphic}}
}
diff --git a/test/SemaCXX/elaborated-type-specifier.cpp b/test/SemaCXX/elaborated-type-specifier.cpp
index 8d2d67f..3cd3a1b 100644
--- a/test/SemaCXX/elaborated-type-specifier.cpp
+++ b/test/SemaCXX/elaborated-type-specifier.cpp
@@ -27,7 +27,7 @@ namespace NS {
void test_X_elab(NS::X x) {
struct S4 *s4 = 0;
- x.test_elab2(s4); // expected-error{{cannot initialize a parameter of type 'struct NS::S4 *' with an lvalue of type 'struct S4 *'}}
+ x.test_elab2(s4); // expected-error{{cannot initialize a parameter of type 'NS::S4 *' with an lvalue of type 'struct S4 *'}}
}
namespace NS {
diff --git a/test/SemaCXX/exception-spec.cpp b/test/SemaCXX/exception-spec.cpp
index 291b359..782cf83 100644
--- a/test/SemaCXX/exception-spec.cpp
+++ b/test/SemaCXX/exception-spec.cpp
@@ -29,10 +29,10 @@ struct Incomplete; // expected-note 3 {{forward declaration}}
// Exception spec must not have incomplete types, or pointers to them, except
// void.
void ic1() throw(void); // expected-error {{incomplete type 'void' is not allowed in exception specification}}
-void ic2() throw(Incomplete); // expected-error {{incomplete type 'struct Incomplete' is not allowed in exception specification}}
+void ic2() throw(Incomplete); // expected-error {{incomplete type 'Incomplete' is not allowed in exception specification}}
void ic3() throw(void*);
-void ic4() throw(Incomplete*); // expected-error {{pointer to incomplete type 'struct Incomplete' is not allowed in exception specification}}
-void ic5() throw(Incomplete&); // expected-error {{reference to incomplete type 'struct Incomplete' is not allowed in exception specification}}
+void ic4() throw(Incomplete*); // expected-error {{pointer to incomplete type 'Incomplete' is not allowed in exception specification}}
+void ic5() throw(Incomplete&); // expected-error {{reference to incomplete type 'Incomplete' is not allowed in exception specification}}
// Redeclarations
typedef int INT;
diff --git a/test/SemaCXX/exceptions.cpp b/test/SemaCXX/exceptions.cpp
index 924b48a..2ed4bfe 100644
--- a/test/SemaCXX/exceptions.cpp
+++ b/test/SemaCXX/exceptions.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-struct A; // expected-note 4 {{forward declaration of 'struct A'}}
+struct A; // expected-note 4 {{forward declaration of 'A'}}
struct Abstract { virtual void f() = 0; }; // expected-note {{pure virtual function 'f'}}
@@ -11,9 +11,9 @@ void trys() {
int i; // expected-error {{redefinition of 'i'}}
} catch(float i) {
} catch(void v) { // expected-error {{cannot catch incomplete type 'void'}}
- } catch(A a) { // expected-error {{cannot catch incomplete type 'struct A'}}
- } catch(A *a) { // expected-error {{cannot catch pointer to incomplete type 'struct A'}}
- } catch(A &a) { // expected-error {{cannot catch reference to incomplete type 'struct A'}}
+ } catch(A a) { // expected-error {{cannot catch incomplete type 'A'}}
+ } catch(A *a) { // expected-warning {{ISO C++ forbids catching a pointer to incomplete type 'A'}}
+ } catch(A &a) { // expected-warning {{ISO C++ forbids catching a reference to incomplete type 'A'}}
} catch(Abstract) { // expected-error {{variable type 'Abstract' is an abstract class}}
} catch(...) {
int j = i; // expected-error {{use of undeclared identifier 'i'}}
@@ -29,7 +29,7 @@ void throws() {
throw;
throw 0;
throw throw; // expected-error {{cannot throw object of incomplete type 'void'}}
- throw (A*)0; // expected-error {{cannot throw pointer to object of incomplete type 'struct A'}}
+ throw (A*)0; // expected-error {{cannot throw pointer to object of incomplete type 'A'}}
}
void jumps() {
diff --git a/test/SemaCXX/functional-cast.cpp b/test/SemaCXX/functional-cast.cpp
index 0bef0cd..4e0486c 100644
--- a/test/SemaCXX/functional-cast.cpp
+++ b/test/SemaCXX/functional-cast.cpp
@@ -175,17 +175,17 @@ void t_529_5_8()
// Bad code below
typedef C1 *C1p;
- (void)C1p((A*)0); // expected-error {{cannot cast 'struct A *' to 'C1p' (aka 'struct C1 *') via virtual base 'struct B'}}
+ (void)C1p((A*)0); // expected-error {{cannot cast 'A *' to 'C1p' (aka 'C1 *') via virtual base 'B'}}
typedef C1 &C1r;
- (void)C1r(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'C1r' (aka 'struct C1 &') via virtual base 'struct B'}}
+ (void)C1r(*((A*)0)); // expected-error {{cannot cast 'A' to 'C1r' (aka 'C1 &') via virtual base 'B'}}
typedef D *Dp;
- (void)Dp((A*)0); // expected-error {{cannot cast 'struct A *' to 'Dp' (aka 'struct D *') via virtual base 'struct B'}}
+ (void)Dp((A*)0); // expected-error {{cannot cast 'A *' to 'Dp' (aka 'D *') via virtual base 'B'}}
typedef D &Dr;
- (void)Dr(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'Dr' (aka 'struct D &') via virtual base 'struct B'}}
+ (void)Dr(*((A*)0)); // expected-error {{cannot cast 'A' to 'Dr' (aka 'D &') via virtual base 'B'}}
typedef H *Hp;
- (void)Hp((A*)0); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
+ (void)Hp((A*)0); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
typedef H &Hr;
- (void)Hr(*((A*)0)); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
+ (void)Hr(*((A*)0)); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
// TODO: Test DR427. This requires user-defined conversions, though.
}
@@ -199,7 +199,7 @@ void t_529_7()
// Bad code below
- (void)Enum((int*)0); // expected-error {{functional-style cast from 'int *' to 'enum Enum' is not allowed}}
+ (void)Enum((int*)0); // expected-error {{functional-style cast from 'int *' to 'Enum' is not allowed}}
}
// Void pointer to object pointer
@@ -219,8 +219,8 @@ void t_529_9()
(void)Amp((int B::*)0);
// Bad code below
- (void)Amp((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'struct H'}}
- (void)Amp((int F::*)0); // expected-error {{conversion from pointer to member of class 'struct F'}}
+ (void)Amp((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'H' to pointer to member of base class 'A':}}
+ (void)Amp((int F::*)0); // expected-error {{conversion from pointer to member of class 'F' to pointer to member of class 'A' via virtual base 'B' is not allowed}}
}
// -------- reinterpret_cast -----------
@@ -304,8 +304,8 @@ void memptrs()
(void)structureimfp(psf);
typedef void (structure::*structurevmfp)();
- (void)structurevmfp(psi); // expected-error {{functional-style cast from 'int const struct structure::*' to 'structurevmfp' (aka 'void (struct structure::*)()') is not allowed}}
- (void)structureimp(psf); // expected-error {{functional-style cast from 'void (struct structure::*)()' to 'structureimp' (aka 'int struct structure::*') is not allowed}}
+ (void)structurevmfp(psi); // expected-error {{functional-style cast from 'int const structure::*' to 'structurevmfp' (aka 'void (structure::*)()') is not allowed}}
+ (void)structureimp(psf); // expected-error {{functional-style cast from 'void (structure::*)()' to 'structureimp' (aka 'int structure::*') is not allowed}}
}
// ---------------- misc ------------------
diff --git a/test/SemaCXX/illegal-member-initialization.cpp b/test/SemaCXX/illegal-member-initialization.cpp
index be5f91d..3fb0b93 100644
--- a/test/SemaCXX/illegal-member-initialization.cpp
+++ b/test/SemaCXX/illegal-member-initialization.cpp
@@ -10,10 +10,10 @@ struct B {
};
struct X {
- X() { } // expected-error {{constructor for 'struct X' must explicitly initialize the reference member 'value'}} \
- // expected-error {{constructor for 'struct X' must explicitly initialize the const member 'cvalue'}} \
- // expected-error {{constructor for 'struct X' must explicitly initialize the reference member 'b'}} \
- // expected-error {{constructor for 'struct X' must explicitly initialize the const member 'cb'}}
+ X() { } // expected-error {{constructor for 'X' must explicitly initialize the reference member 'value'}} \
+ // expected-error {{constructor for 'X' must explicitly initialize the const member 'cvalue'}} \
+ // expected-error {{constructor for 'X' must explicitly initialize the reference member 'b'}} \
+ // expected-error {{constructor for 'X' must explicitly initialize the const member 'cb'}}
int &value; // expected-note{{declared at}}
const int cvalue; // expected-note{{declared at}}
B& b; // expected-note{{declared at}}
diff --git a/test/SemaCXX/implicit-virtual-member-functions.cpp b/test/SemaCXX/implicit-virtual-member-functions.cpp
index 1bb5adb..cb24501 100644
--- a/test/SemaCXX/implicit-virtual-member-functions.cpp
+++ b/test/SemaCXX/implicit-virtual-member-functions.cpp
@@ -9,7 +9,7 @@ struct B : A { // expected-error {{no suitable member 'operator delete' in 'B'}}
void operator delete (void *, int); // expected-note {{'operator delete' declared here}}
};
-void B::f() { // expected-note {{implicit default destructor for 'struct B' first required here}}
+void B::f() { // expected-note {{implicit default destructor for 'B' first required here}}
}
struct C : A { // expected-error {{no suitable member 'operator delete' in 'C'}}
@@ -17,11 +17,11 @@ struct C : A { // expected-error {{no suitable member 'operator delete' in 'C'}}
void operator delete(void *, int); // expected-note {{'operator delete' declared here}}
};
-C::C() { } // expected-note {{implicit default destructor for 'struct C' first required here}}
+C::C() { } // expected-note {{implicit default destructor for 'C' first required here}}
struct D : A { // expected-error {{no suitable member 'operator delete' in 'D'}}
void operator delete(void *, int); // expected-note {{'operator delete' declared here}}
-}; // expected-note {{implicit default destructor for 'struct D' first required here}}
+}; // expected-note {{implicit default destructor for 'D' first required here}}
void f() {
new D;
diff --git a/test/SemaCXX/incomplete-call.cpp b/test/SemaCXX/incomplete-call.cpp
index 5bdaf82..d627c33 100644
--- a/test/SemaCXX/incomplete-call.cpp
+++ b/test/SemaCXX/incomplete-call.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-struct A; // expected-note 14 {{forward declaration of 'struct A'}}
+struct A; // expected-note 14 {{forward declaration of 'A'}}
A f(); // expected-note {{note: 'f' declared here}}
@@ -15,29 +15,29 @@ struct B {
};
void g() {
- f(); // expected-error {{calling 'f' with incomplete return type 'struct A'}}
+ f(); // expected-error {{calling 'f' with incomplete return type 'A'}}
typedef A (*Func)();
Func fp;
- fp(); // expected-error {{calling function with incomplete return type 'struct A'}}
- ((Func)0)(); // expected-error {{calling function with incomplete return type 'struct A'}}
+ fp(); // expected-error {{calling function with incomplete return type 'A'}}
+ ((Func)0)(); // expected-error {{calling function with incomplete return type 'A'}}
B b;
- b.f(); // expected-error {{calling 'f' with incomplete return type 'struct A'}}
+ b.f(); // expected-error {{calling 'f' with incomplete return type 'A'}}
- b.operator()(); // expected-error {{calling 'operator()' with incomplete return type 'struct A'}}
- b.operator A(); // expected-error {{calling 'operator A' with incomplete return type 'struct A'}}
- b.operator!(); // expected-error {{calling 'operator!' with incomplete return type 'struct A'}}
+ b.operator()(); // expected-error {{calling 'operator()' with incomplete return type 'A'}}
+ b.operator A(); // expected-error {{calling 'operator A' with incomplete return type 'A'}}
+ b.operator!(); // expected-error {{calling 'operator!' with incomplete return type 'A'}}
- !b; // expected-error {{calling 'operator!' with incomplete return type 'struct A'}}
- b(); // expected-error {{calling 'operator()' with incomplete return type 'struct A'}}
- b++; // expected-error {{calling 'operator++' with incomplete return type 'struct A'}}
- b[0]; // expected-error {{calling 'operator[]' with incomplete return type 'struct A'}}
- b + 1; // expected-error {{calling 'operator+' with incomplete return type 'struct A'}}
- b->f(); // expected-error {{calling 'operator->' with incomplete return type 'struct A'}}
+ !b; // expected-error {{calling 'operator!' with incomplete return type 'A'}}
+ b(); // expected-error {{calling 'operator()' with incomplete return type 'A'}}
+ b++; // expected-error {{calling 'operator++' with incomplete return type 'A'}}
+ b[0]; // expected-error {{calling 'operator[]' with incomplete return type 'A'}}
+ b + 1; // expected-error {{calling 'operator+' with incomplete return type 'A'}}
+ b->f(); // expected-error {{calling 'operator->' with incomplete return type 'A'}}
A (B::*mfp)() = 0;
- (b.*mfp)(); // expected-error {{calling function with incomplete return type 'struct A'}}
+ (b.*mfp)(); // expected-error {{calling function with incomplete return type 'A'}}
}
diff --git a/test/SemaCXX/inherit.cpp b/test/SemaCXX/inherit.cpp
index aabed2b..a926c81 100644
--- a/test/SemaCXX/inherit.cpp
+++ b/test/SemaCXX/inherit.cpp
@@ -10,7 +10,7 @@ class B3 : virtual virtual A { }; // expected-error{{duplicate 'virtual' in base
class C : public B1, private B2 { };
-class D; // expected-note {{forward declaration of 'class D'}}
+class D; // expected-note {{forward declaration of 'D'}}
class E : public D { }; // expected-error{{base class has incomplete type}}
@@ -28,5 +28,5 @@ typedef G G_copy;
typedef G G_copy_2;
typedef G_copy G_copy_3;
-class H : G_copy, A, G_copy_2, // expected-error{{base class 'G_copy' (aka 'class G') specified more than once as a direct base class}}
- public G_copy_3 { }; // expected-error{{base class 'G_copy' (aka 'class G') specified more than once as a direct base class}}
+class H : G_copy, A, G_copy_2, // expected-error{{base class 'G_copy' (aka 'G') specified more than once as a direct base class}}
+ public G_copy_3 { }; // expected-error{{base class 'G_copy' (aka 'G') specified more than once as a direct base class}}
diff --git a/test/SemaCXX/member-name-lookup.cpp b/test/SemaCXX/member-name-lookup.cpp
index 94296e1..0149169 100644
--- a/test/SemaCXX/member-name-lookup.cpp
+++ b/test/SemaCXX/member-name-lookup.cpp
@@ -35,11 +35,11 @@ struct D : B, C {
};
void test_lookup(D d) {
- d.a; // expected-error{{non-static member 'a' found in multiple base-class subobjects of type 'struct A'}}
+ d.a; // expected-error{{non-static member 'a' found in multiple base-class subobjects of type 'A':}}
(void)d.b; // okay
d.c; // expected-error{{member 'c' found in multiple base classes of different types}}
d.d; // expected-error{{member 'd' found in multiple base classes of different types}}
- d.f(0); // expected-error{{non-static member 'f' found in multiple base-class subobjects of type 'struct A'}}
+ d.f(0); // expected-error{{non-static member 'f' found in multiple base-class subobjects of type 'A':}}
d.static_f(0); // okay
D::E e = D::enumerator; // okay
@@ -51,11 +51,11 @@ void test_lookup(D d) {
}
void D::test_lookup() {
- a; // expected-error{{non-static member 'a' found in multiple base-class subobjects of type 'struct A'}}
+ a; // expected-error{{non-static member 'a' found in multiple base-class subobjects of type 'A':}}
(void)b; // okay
c; // expected-error{{member 'c' found in multiple base classes of different types}}
d; // expected-error{{member 'd' found in multiple base classes of different types}}
- f(0); // expected-error{{non-static member 'f' found in multiple base-class subobjects of type 'struct A'}}
+ f(0); // expected-error{{non-static member 'f' found in multiple base-class subobjects of type 'A':}}
static_f(0); // okay
E e = enumerator; // okay
@@ -105,7 +105,7 @@ void test_virtual_lookup(D2 d2, G g) {
D2::E3 e3; // expected-error{{member 'E3' found in multiple base classes of different types}}
- g.a; // expected-error{{non-static member 'a' found in multiple base-class subobjects of type 'struct A'}}
+ g.a; // expected-error{{non-static member 'a' found in multiple base-class subobjects of type 'A':}}
g.static_f(0); // okay
}
@@ -126,7 +126,7 @@ void D2::test_virtual_lookup() {
}
void G::test_virtual_lookup() {
- a; // expected-error{{non-static member 'a' found in multiple base-class subobjects of type 'struct A'}}
+ a; // expected-error{{non-static member 'a' found in multiple base-class subobjects of type 'A':}}
static_f(0); // okay
}
diff --git a/test/SemaCXX/member-pointer.cpp b/test/SemaCXX/member-pointer.cpp
index d6050cd..92ae92d 100644
--- a/test/SemaCXX/member-pointer.cpp
+++ b/test/SemaCXX/member-pointer.cpp
@@ -34,11 +34,11 @@ void f() {
pdid = pdi2;
// Fail conversion due to ambiguity and virtuality.
- int F::*pdif = pdi1; // expected-error {{ambiguous conversion from pointer to member of base class 'struct A' to pointer to member of derived class 'struct F'}}
- int G::*pdig = pdi1; // expected-error {{conversion from pointer to member of class 'struct A' to pointer to member of class 'struct G' via virtual base 'struct D' is not allowed}}
+ int F::*pdif = pdi1; // expected-error {{ambiguous conversion from pointer to member of base class 'A' to pointer to member of derived class 'F':}}
+ int G::*pdig = pdi1; // expected-error {{conversion from pointer to member of class 'A' to pointer to member of class 'G' via virtual base 'D' is not allowed}}
// Conversion to member of base.
- pdi1 = pdid; // expected-error {{incompatible type assigning 'int struct D::*', expected 'int struct A::*'}}
+ pdi1 = pdid; // expected-error {{incompatible type assigning 'int D::*', expected 'int A::*'}}
// Comparisons
int (A::*pf2)(int, int);
@@ -104,8 +104,8 @@ void h() {
(hm.*pf)();
(phm->*pf)();
- (void)(hm->*pi); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'struct HasMembers'}}
- (void)(phm.*pi); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'struct HasMembers *'}}
+ (void)(hm->*pi); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'HasMembers'}}
+ (void)(phm.*pi); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'HasMembers *'}}
(void)(i.*pi); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'int'}}
int *ptr;
(void)(ptr->*pi); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'int *'}}
@@ -115,8 +115,8 @@ void h() {
(void)(d.*pai);
(void)(pd->*pai);
F f, *ptrf = &f;
- (void)(f.*pai); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'struct F'}}
- (void)(ptrf->*pai); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'struct F *'}}
+ (void)(f.*pai); // expected-error {{left hand operand to .* must be a class compatible with the right hand operand, but is 'F'}}
+ (void)(ptrf->*pai); // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'F *'}}
(void)(hm.*i); // expected-error {{pointer-to-member}}
(void)(phm->*i); // expected-error {{pointer-to-member}}
diff --git a/test/SemaCXX/missing-members.cpp b/test/SemaCXX/missing-members.cpp
index 9ec17f7..529ba10 100644
--- a/test/SemaCXX/missing-members.cpp
+++ b/test/SemaCXX/missing-members.cpp
@@ -9,7 +9,7 @@ namespace A {
void f() {
A::B::i; // expected-error {{no member named 'i' in namespace 'A::B'}}
- A::B::C::i; // expected-error {{no member named 'i' in 'class A::B::C'}}
+ A::B::C::i; // expected-error {{no member named 'i' in 'A::B::C'}}
::i; // expected-error {{no member named 'i' in the global namespace}}
}
@@ -19,18 +19,18 @@ namespace B {
void g() {
A::B::D::E; // expected-error {{no member named 'D' in namespace 'A::B'}}
- B::B::C::D; // expected-error {{no member named 'C' in 'class B::B'}}
+ B::B::C::D; // expected-error {{no member named 'C' in 'B::B'}}
::C::D; // expected-error {{no member named 'C' in the global namespace}}
}
int A::B::i = 10; // expected-error {{no member named 'i' in namespace 'A::B'}}
-int A::B::C::i = 10; // expected-error {{no member named 'i' in 'class A::B::C'}}
-int A::B::S::i = 10; // expected-error {{no member named 'i' in 'struct A::B::S'}}
-int A::B::U::i = 10; // expected-error {{no member named 'i' in 'union A::B::U'}}
+int A::B::C::i = 10; // expected-error {{no member named 'i' in 'A::B::C'}}
+int A::B::S::i = 10; // expected-error {{no member named 'i' in 'A::B::S'}}
+int A::B::U::i = 10; // expected-error {{no member named 'i' in 'A::B::U'}}
using A::B::D; // expected-error {{no member named 'D' in namespace 'A::B'}}
struct S : A::B::C {
- using A::B::C::f; // expected-error {{no member named 'f' in 'class A::B::C'}}
+ using A::B::C::f; // expected-error {{no member named 'f' in 'A::B::C'}}
};
diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp
index 247e91b..8657c0d 100644
--- a/test/SemaCXX/nested-name-spec.cpp
+++ b/test/SemaCXX/nested-name-spec.cpp
@@ -36,9 +36,9 @@ class C2 {
int x;
};
-void C2::m() const { } // expected-error{{out-of-line definition of 'm' does not match any declaration in 'class C2'}}
+void C2::m() const { } // expected-error{{out-of-line definition of 'm' does not match any declaration in 'C2'}}
-void C2::f(int) { } // expected-error{{out-of-line definition of 'f' does not match any declaration in 'class C2'}}
+void C2::f(int) { } // expected-error{{out-of-line definition of 'f' does not match any declaration in 'C2'}}
void C2::m() {
x = 0;
@@ -125,7 +125,7 @@ class Operators {
operator bool();
};
-Operators Operators::operator+(const Operators&) { // expected-error{{out-of-line definition of 'operator+' does not match any declaration in 'class Operators'}}
+Operators Operators::operator+(const Operators&) { // expected-error{{out-of-line definition of 'operator+' does not match any declaration in 'Operators'}}
Operators ops;
return ops;
}
@@ -149,7 +149,7 @@ void A::g(const int&) { } // expected-error{{out-of-line definition of 'g' does
struct Struct { };
-void Struct::f() { } // expected-error{{out-of-line definition of 'f' does not match any declaration in 'struct Struct'}}
+void Struct::f() { } // expected-error{{out-of-line definition of 'f' does not match any declaration in 'Struct'}}
void global_func(int);
void global_func2(int);
@@ -164,8 +164,8 @@ void ::global_func2(int) { } // expected-error{{definition or redeclaration of '
void N::f() { } // okay
-struct Y; // expected-note{{forward declaration of 'struct Y'}}
-Y::foo y; // expected-error{{incomplete type 'struct Y' named in nested name specifier}} \
+struct Y; // expected-note{{forward declaration of 'Y'}}
+Y::foo y; // expected-error{{incomplete type 'Y' named in nested name specifier}} \
// expected-error{{no type named 'foo' in}}
X::X() : a(5) { } // expected-error{{use of undeclared identifier 'X'}} \
@@ -227,6 +227,6 @@ namespace test3 {
// FIXME: this should really only trigger once
class A; // expected-note 2 {{forward declaration}}
void foo(const char *path) {
- A::execute(path); // expected-error 2 {{incomplete type 'class test3::A' named in nested name specifier}}
+ A::execute(path); // expected-error 2 {{incomplete type 'test3::A' named in nested name specifier}}
}
}
diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp
index 68323d8..ae77e70 100644
--- a/test/SemaCXX/new-delete.cpp
+++ b/test/SemaCXX/new-delete.cpp
@@ -8,7 +8,7 @@ struct S // expected-note {{candidate}}
S(double, int); // expected-note 2 {{candidate}}
S(float, int); // expected-note 2 {{candidate}}
};
-struct T; // expected-note{{forward declaration of 'struct T'}}
+struct T; // expected-note{{forward declaration of 'T'}}
struct U
{
// A special new, to verify that the global version isn't used.
@@ -60,15 +60,15 @@ void bad_news(int *ip)
(void)new int[1][i]; // expected-error {{only the first dimension}}
(void)new (int[1][i]); // expected-error {{only the first dimension}}
(void)new (int[i]); // expected-error {{when type is in parentheses}}
- (void)new int(*(S*)0); // expected-error {{no viable conversion from 'struct S' to 'int'}}
+ (void)new int(*(S*)0); // expected-error {{no viable conversion from 'S' to 'int'}}
(void)new int(1, 2); // expected-error {{excess elements in scalar initializer}}
(void)new S(1); // expected-error {{no matching constructor}}
- (void)new S(1, 1); // expected-error {{call to constructor of 'struct S' is ambiguous}}
+ (void)new S(1, 1); // expected-error {{call to constructor of 'S' is ambiguous}}
(void)new const int; // expected-error {{default initialization of an object of const type 'int const'}}
(void)new float*(ip); // expected-error {{cannot initialize a new value of type 'float *' with an lvalue of type 'int *'}}
// Undefined, but clang should reject it directly.
(void)new int[-1]; // expected-error {{array size is negative}}
- (void)new int[*(S*)0]; // expected-error {{array size expression must have integral or enumerated type, not 'struct S'}}
+ (void)new int[*(S*)0]; // expected-error {{array size expression must have integral or enumerated type, not 'S'}}
(void)::S::new int; // expected-error {{expected unqualified-id}}
(void)new (0, 0) int; // expected-error {{no matching function for call to 'operator new'}}
(void)new (0L) int; // expected-error {{call to 'operator new' is ambiguous}}
@@ -114,7 +114,7 @@ struct X2 {
void test_delete_conv(X0 x0, X1 x1, X2 x2) {
delete x0; // expected-error{{cannot delete}}
delete x1;
- delete x2; // expected-error{{ambiguous conversion of delete expression of type 'struct X2' to a pointer}}
+ delete x2; // expected-error{{ambiguous conversion of delete expression of type 'X2' to a pointer}}
}
// PR4782
@@ -199,7 +199,7 @@ struct X11 : X10 { // expected-error {{no suitable member 'operator delete' in '
};
void f() {
- X11 x11; // expected-note {{implicit default destructor for 'struct X11' first required here}}
+ X11 x11; // expected-note {{implicit default destructor for 'X11' first required here}}
}
struct X12 {
diff --git a/test/SemaCXX/offsetof.cpp b/test/SemaCXX/offsetof.cpp
index f3dc52d..3283270 100644
--- a/test/SemaCXX/offsetof.cpp
+++ b/test/SemaCXX/offsetof.cpp
@@ -10,7 +10,7 @@ struct P {
};
void f() {
- int i = __builtin_offsetof(P, fieldThatPointsToANonPODType.m); // expected-warning{{offset of on non-POD type 'struct P'}}
+ int i = __builtin_offsetof(P, fieldThatPointsToANonPODType.m); // expected-warning{{offset of on non-POD type 'P'}}
}
struct Base { int x; };
diff --git a/test/SemaCXX/overload-call.cpp b/test/SemaCXX/overload-call.cpp
index 77e0908..c286028 100644
--- a/test/SemaCXX/overload-call.cpp
+++ b/test/SemaCXX/overload-call.cpp
@@ -386,3 +386,23 @@ namespace DerivedToBase {
float &fr = f0(C());
}
}
+
+namespace PR6483 {
+ struct X0 {
+ operator const unsigned int & () const;
+ };
+
+ struct X1 {
+ operator unsigned int & () const;
+ };
+
+ void f0(const bool &);
+ void f1(bool &); // expected-note 2{{not viable}}
+
+ void g(X0 x0, X1 x1) {
+ f0(x0);
+ f1(x0); // expected-error{{no matching function for call}}
+ f0(x1);
+ f1(x1); // expected-error{{no matching function for call}}
+ }
+}
diff --git a/test/SemaCXX/overload-member-call.cpp b/test/SemaCXX/overload-member-call.cpp
index 77d9965..8016b11 100644
--- a/test/SemaCXX/overload-member-call.cpp
+++ b/test/SemaCXX/overload-member-call.cpp
@@ -78,11 +78,11 @@ namespace test1 {
void foo(int n, const char *s, int t, ...); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}}
void foo(int n, const char *s, int t, int u = 0); // expected-note {{candidate function not viable: requires at least 3 arguments, but 2 were provided}}
- void bar(double d); //expected-note {{candidate function not viable: 'this' argument has type 'class test1::A const', but method is not marked const}}
- void bar(int i); //expected-note {{candidate function not viable: 'this' argument has type 'class test1::A const', but method is not marked const}}
+ void bar(double d); //expected-note {{candidate function not viable: 'this' argument has type 'test1::A const', but method is not marked const}}
+ void bar(int i); //expected-note {{candidate function not viable: 'this' argument has type 'test1::A const', but method is not marked const}}
- void baz(A &d); // expected-note {{candidate function not viable: 1st argument ('class test1::A const') would lose const qualifier}}
- void baz(int i); // expected-note {{candidate function not viable: no known conversion from 'class test1::A const' to 'int' for 1st argument}}
+ void baz(A &d); // expected-note {{candidate function not viable: 1st argument ('test1::A const') would lose const qualifier}}
+ void baz(int i); // expected-note {{candidate function not viable: no known conversion from 'test1::A const' to 'int' for 1st argument}}
};
void test() {
diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp
index e07afe2..89f1814 100644
--- a/test/SemaCXX/overloaded-operator.cpp
+++ b/test/SemaCXX/overloaded-operator.cpp
@@ -38,7 +38,7 @@ bool operator==(A&, Z&); // expected-note 2{{candidate function}}
void h(A a, const A ac, Z z) {
make_A() == z;
a == z; // expected-error{{use of overloaded operator '==' is ambiguous; candidates are:}}
- ac == z; // expected-error{{invalid operands to binary expression ('struct A const' and 'struct Z')}}
+ ac == z; // expected-error{{invalid operands to binary expression ('A const' and 'Z')}}
}
struct B {
@@ -172,7 +172,7 @@ void test_callable(Callable c, Callable2 c2, const Callable2& c2c,
int &ir = c(1);
float &fr = c(1, 3.14159, 17, 42);
- c(); // expected-error{{no matching function for call to object of type 'struct Callable'; candidates are:}}
+ c(); // expected-error{{no matching function for call to object of type 'Callable'}}
double &dr = c(1.0f);
@@ -200,12 +200,12 @@ struct ConvertToFuncDerived : ConvertToFunc { };
void test_funcptr_call(ConvertToFunc ctf, ConvertToFuncDerived ctfd) {
int &i1 = ctf(1.0f, 2.0);
float &f1 = ctf((short int)1, 1.0f);
- ctf((long int)17, 2.0); // expected-error{{error: call to object of type 'struct ConvertToFunc' is ambiguous; candidates are:}}
+ ctf((long int)17, 2.0); // expected-error{{call to object of type 'ConvertToFunc' is ambiguous}}
ctf();
int &i2 = ctfd(1.0f, 2.0);
float &f2 = ctfd((short int)1, 1.0f);
- ctfd((long int)17, 2.0); // expected-error{{error: call to object of type 'struct ConvertToFuncDerived' is ambiguous; candidates are:}}
+ ctfd((long int)17, 2.0); // expected-error{{call to object of type 'ConvertToFuncDerived' is ambiguous}}
ctfd();
}
diff --git a/test/SemaCXX/qual-id-test.cpp b/test/SemaCXX/qual-id-test.cpp
index 00dc662..54d41b8 100644
--- a/test/SemaCXX/qual-id-test.cpp
+++ b/test/SemaCXX/qual-id-test.cpp
@@ -48,7 +48,7 @@ namespace C
a.A::sub::x();
a.A::B::base::x();
- a.bad::x(); // expected-error{{type 'struct bad' is not a direct or virtual base of ''A::sub''}}
+ a.bad::x(); // expected-error{{type 'bad' is not a direct or virtual base of ''A::sub''}}
a->foo();
a->member::foo();
@@ -69,7 +69,7 @@ namespace C
a->A::sub::x();
a->A::B::base::x();
- a->bad::x(); // expected-error{{type 'struct bad' is not a direct or virtual base of ''A::sub''}}
+ a->bad::x(); // expected-error{{type 'bad' is not a direct or virtual base of ''A::sub''}}
(*a)->foo();
(*a)->member::foo();
diff --git a/test/SemaCXX/qualified-id-lookup.cpp b/test/SemaCXX/qualified-id-lookup.cpp
index a187d49..abde62e 100644
--- a/test/SemaCXX/qualified-id-lookup.cpp
+++ b/test/SemaCXX/qualified-id-lookup.cpp
@@ -96,12 +96,12 @@ void test_a() {
a::a::a::i = 4;
}
-struct Undef { // expected-note{{definition of 'struct Undef' is not complete until the closing '}'}}
+struct Undef { // expected-note{{definition of 'Undef' is not complete until the closing '}'}}
typedef int type;
Undef::type member;
- static int size = sizeof(Undef); // expected-error{{invalid application of 'sizeof' to an incomplete type 'struct Undef'}}
+ static int size = sizeof(Undef); // expected-error{{invalid application of 'sizeof' to an incomplete type 'Undef'}}
int f();
};
diff --git a/test/SemaCXX/qualified-names-diag.cpp b/test/SemaCXX/qualified-names-diag.cpp
index 86c1088..c8b5746 100644
--- a/test/SemaCXX/qualified-names-diag.cpp
+++ b/test/SemaCXX/qualified-names-diag.cpp
@@ -16,7 +16,7 @@ namespace foo {
namespace bar {
typedef int y;
- struct incomplete; // expected-note{{forward declaration of 'struct bar::incomplete'}}
+ struct incomplete; // expected-note{{forward declaration of 'bar::incomplete'}}
}
void test() {
foo::wibble::x a;
diff --git a/test/SemaCXX/ref-init-ambiguous.cpp b/test/SemaCXX/ref-init-ambiguous.cpp
index 976879e..8844162 100644
--- a/test/SemaCXX/ref-init-ambiguous.cpp
+++ b/test/SemaCXX/ref-init-ambiguous.cpp
@@ -14,15 +14,15 @@ struct C : B, A {
};
void test(C c) {
- const E2 &e2 = c; // expected-error {{reference initialization of type 'enum E2 const &' with initializer of type 'struct C' is ambiguous}}
+ const E2 &e2 = c; // expected-error {{reference initialization of type 'E2 const &' with initializer of type 'C' is ambiguous}}
}
void foo(const E2 &);
const E2 & re(C c) {
- foo(c); // expected-error {{reference initialization of type 'enum E2 const &' with initializer of type 'struct C' is ambiguous}}
+ foo(c); // expected-error {{reference initialization of type 'E2 const &' with initializer of type 'C' is ambiguous}}
- return c; // expected-error {{reference initialization of type 'enum E2 const &' with initializer of type 'struct C' is ambiguous}}
+ return c; // expected-error {{reference initialization of type 'E2 const &' with initializer of type 'C' is ambiguous}}
}
diff --git a/test/SemaCXX/references.cpp b/test/SemaCXX/references.cpp
index df8337b..f1f4ab9 100644
--- a/test/SemaCXX/references.cpp
+++ b/test/SemaCXX/references.cpp
@@ -73,7 +73,7 @@ class Test6 {
struct C : B, A { };
void test7(C& c) {
- A& a1 = c; // expected-error {{ambiguous conversion from derived class 'struct C' to base class 'struct A':}}
+ A& a1 = c; // expected-error {{ambiguous conversion from derived class 'C' to base class 'A':}}
}
// C++ [dcl.ref]p1, C++ [dcl.ref]p4
diff --git a/test/SemaCXX/reinterpret-cast.cpp b/test/SemaCXX/reinterpret-cast.cpp
index f7ab80e..45d41e8 100644
--- a/test/SemaCXX/reinterpret-cast.cpp
+++ b/test/SemaCXX/reinterpret-cast.cpp
@@ -13,7 +13,7 @@ void self_conversion()
int i = 0;
(void)reinterpret_cast<int>(i); // expected-error {{reinterpret_cast from 'int' to 'int' is not allowed}}
structure s;
- (void)reinterpret_cast<structure>(s); // expected-error {{reinterpret_cast from 'struct structure' to 'struct structure' is not allowed}}
+ (void)reinterpret_cast<structure>(s); // expected-error {{reinterpret_cast from 'structure' to 'structure' is not allowed}}
int *pi = 0;
(void)reinterpret_cast<int*>(pi);
}
@@ -77,18 +77,18 @@ void memptrs()
{
const int structure::*psi = 0;
(void)reinterpret_cast<const float structure::*>(psi);
- (void)reinterpret_cast<int structure::*>(psi); // expected-error {{reinterpret_cast from 'int const struct structure::*' to 'int struct structure::*' casts away constness}}
+ (void)reinterpret_cast<int structure::*>(psi); // expected-error {{reinterpret_cast from 'int const structure::*' to 'int structure::*' casts away constness}}
void (structure::*psf)() = 0;
(void)reinterpret_cast<int (structure::*)()>(psf);
- (void)reinterpret_cast<void (structure::*)()>(psi); // expected-error {{reinterpret_cast from 'int const struct structure::*' to 'void (struct structure::*)()' is not allowed}}
- (void)reinterpret_cast<int structure::*>(psf); // expected-error {{reinterpret_cast from 'void (struct structure::*)()' to 'int struct structure::*' is not allowed}}
+ (void)reinterpret_cast<void (structure::*)()>(psi); // expected-error {{reinterpret_cast from 'int const structure::*' to 'void (structure::*)()' is not allowed}}
+ (void)reinterpret_cast<int structure::*>(psf); // expected-error {{reinterpret_cast from 'void (structure::*)()' to 'int structure::*' is not allowed}}
// Cannot cast from integers to member pointers, not even the null pointer
// literal.
- (void)reinterpret_cast<void (structure::*)()>(0); // expected-error {{reinterpret_cast from 'int' to 'void (struct structure::*)()' is not allowed}}
- (void)reinterpret_cast<int structure::*>(0); // expected-error {{reinterpret_cast from 'int' to 'int struct structure::*' is not allowed}}
+ (void)reinterpret_cast<void (structure::*)()>(0); // expected-error {{reinterpret_cast from 'int' to 'void (structure::*)()' is not allowed}}
+ (void)reinterpret_cast<int structure::*>(0); // expected-error {{reinterpret_cast from 'int' to 'int structure::*' is not allowed}}
}
// PR5545
diff --git a/test/SemaCXX/rval-references.cpp b/test/SemaCXX/rval-references.cpp
index 2a7fb25..d5b465f 100644
--- a/test/SemaCXX/rval-references.cpp
+++ b/test/SemaCXX/rval-references.cpp
@@ -44,7 +44,7 @@ void f() {
conv_to_not_int_rvalue cnir;
not_int &&ni4 = cnir; // expected-error {{rvalue reference cannot bind to lvalue}}
- not_int &ni5 = cnir; // expected-error{{non-const lvalue reference to type 'struct not_int' cannot bind to a value of unrelated type 'struct conv_to_not_int_rvalue'}}
+ not_int &ni5 = cnir; // expected-error{{non-const lvalue reference to type 'not_int' cannot bind to a value of unrelated type 'conv_to_not_int_rvalue'}}
not_int &&ni6 = conv_to_not_int_rvalue();
@@ -83,5 +83,5 @@ MoveOnly returningNonEligible() {
else if (0) // Copy from reference can't be elided
return r; // expected-error {{call to deleted constructor}}
else // Construction from different type can't be elided
- return i; // expected-error {{no viable conversion from 'int' to 'struct MoveOnly'}}
+ return i; // expected-error {{no viable conversion from 'int' to 'MoveOnly'}}
}
diff --git a/test/SemaCXX/statements.cpp b/test/SemaCXX/statements.cpp
index 852086e..0e27f46 100644
--- a/test/SemaCXX/statements.cpp
+++ b/test/SemaCXX/statements.cpp
@@ -15,3 +15,8 @@ void test2() {
later:
;
}
+
+namespace PR6536 {
+ struct A {};
+ void a() { goto out; A x; out: return; }
+}
diff --git a/test/SemaCXX/static-assert.cpp b/test/SemaCXX/static-assert.cpp
index 62208cd..516243e 100644
--- a/test/SemaCXX/static-assert.cpp
+++ b/test/SemaCXX/static-assert.cpp
@@ -18,13 +18,13 @@ template<int N> struct T {
static_assert(N == 2, "N is not 2!"); // expected-error {{static_assert failed "N is not 2!"}}
};
-T<1> t1; // expected-note {{in instantiation of template class 'struct T<1>' requested here}}
+T<1> t1; // expected-note {{in instantiation of template class 'T<1>' requested here}}
T<2> t2;
template<typename T> struct S {
static_assert(sizeof(T) > sizeof(char), "Type not big enough!"); // expected-error {{static_assert failed "Type not big enough!"}}
};
-S<char> s1; // expected-note {{in instantiation of template class 'struct S<char>' requested here}}
+S<char> s1; // expected-note {{in instantiation of template class 'S<char>' requested here}}
S<int> s2;
diff --git a/test/SemaCXX/static-cast-complete-type.cpp b/test/SemaCXX/static-cast-complete-type.cpp
index 11bf22d..6d76f81 100644
--- a/test/SemaCXX/static-cast-complete-type.cpp
+++ b/test/SemaCXX/static-cast-complete-type.cpp
@@ -3,11 +3,11 @@ template<typename T> struct S {
S(int);
};
-struct T; // expected-note{{forward declaration of 'struct T'}}
+struct T; // expected-note{{forward declaration of 'T'}}
void f() {
S<int> s0 = static_cast<S<int> >(0);
S<void*> s1 = static_cast<S<void*> >(00);
- (void)static_cast<T>(10); // expected-error{{'struct T' is an incomplete type}}
+ (void)static_cast<T>(10); // expected-error{{'T' is an incomplete type}}
}
diff --git a/test/SemaCXX/static-cast.cpp b/test/SemaCXX/static-cast.cpp
index 4818b04..2630278 100644
--- a/test/SemaCXX/static-cast.cpp
+++ b/test/SemaCXX/static-cast.cpp
@@ -56,10 +56,10 @@ void t_529_2()
// Bad code below
(void)static_cast<void*>((const int*)0); // expected-error {{static_cast from 'int const *' to 'void *' is not allowed}}
- (void)static_cast<A*>((E*)0); // expected-error {{private base class 'struct A'}}
+ (void)static_cast<A*>((E*)0); // expected-error {{cannot cast 'E' to its private base class 'A'}}
(void)static_cast<A*>((H*)0); // expected-error {{ambiguous conversion}}
(void)static_cast<int>((int*)0); // expected-error {{static_cast from 'int *' to 'int' is not allowed}}
- (void)static_cast<A**>((B**)0); // expected-error {{static_cast from 'struct B **' to 'struct A **' is not allowed}}
+ (void)static_cast<A**>((B**)0); // expected-error {{static_cast from 'B **' to 'A **' is not allowed}}
(void)static_cast<char&>(i); // expected-error {{non-const lvalue reference to type 'char' cannot be initialized with a value of type 'int'}}
}
@@ -80,18 +80,18 @@ void t_529_5_8()
// Bad code below
- (void)static_cast<C1*>((A*)0); // expected-error {{cannot cast 'struct A *' to 'struct C1 *' via virtual base 'struct B'}}
- (void)static_cast<C1&>(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct C1 &' via virtual base 'struct B'}}
- (void)static_cast<D*>((A*)0); // expected-error {{cannot cast 'struct A *' to 'struct D *' via virtual base 'struct B'}}
- (void)static_cast<D&>(*((A*)0)); // expected-error {{cannot cast 'struct A' to 'struct D &' via virtual base 'struct B'}}
- (void)static_cast<B*>((const A*)0); // expected-error {{static_cast from 'struct A const *' to 'struct B *' casts away constness}}
- (void)static_cast<B&>(*((const A*)0)); // expected-error {{static_cast from 'struct A const' to 'struct B &' casts away constness}}
- (void)static_cast<E*>((A*)0); // expected-error {{cannot cast private base class 'struct A' to 'struct E'}}
- (void)static_cast<E&>(*((A*)0)); // expected-error {{cannot cast private base class 'struct A' to 'struct E'}}
- (void)static_cast<H*>((A*)0); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
- (void)static_cast<H&>(*((A*)0)); // expected-error {{ambiguous cast from base 'struct A' to derived 'struct H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
- (void)static_cast<E*>((B*)0); // expected-error {{static_cast from 'struct B *' to 'struct E *' is not allowed}}
- (void)static_cast<E&>(*((B*)0)); // expected-error {{non-const lvalue reference to type 'struct E' cannot be initialized with a value of type 'struct B'}}
+ (void)static_cast<C1*>((A*)0); // expected-error {{cannot cast 'A *' to 'C1 *' via virtual base 'B'}}
+ (void)static_cast<C1&>(*((A*)0)); // expected-error {{cannot cast 'A' to 'C1 &' via virtual base 'B'}}
+ (void)static_cast<D*>((A*)0); // expected-error {{cannot cast 'A *' to 'D *' via virtual base 'B'}}
+ (void)static_cast<D&>(*((A*)0)); // expected-error {{cannot cast 'A' to 'D &' via virtual base 'B'}}
+ (void)static_cast<B*>((const A*)0); // expected-error {{static_cast from 'A const *' to 'B *' casts away constness}}
+ (void)static_cast<B&>(*((const A*)0)); // expected-error {{static_cast from 'A const' to 'B &' casts away constness}}
+ (void)static_cast<E*>((A*)0); // expected-error {{cannot cast private base class 'A' to 'E'}}
+ (void)static_cast<E&>(*((A*)0)); // expected-error {{cannot cast private base class 'A' to 'E'}}
+ (void)static_cast<H*>((A*)0); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
+ (void)static_cast<H&>(*((A*)0)); // expected-error {{ambiguous cast from base 'A' to derived 'H':\n struct A -> struct B -> struct G1 -> struct H\n struct A -> struct B -> struct G2 -> struct H}}
+ (void)static_cast<E*>((B*)0); // expected-error {{static_cast from 'B *' to 'E *' is not allowed}}
+ (void)static_cast<E&>(*((B*)0)); // expected-error {{non-const lvalue reference to type 'E' cannot be initialized with a value of type 'B'}}
// TODO: Test inaccessible base in context where it's accessible, i.e.
// member function and friend.
@@ -108,7 +108,7 @@ void t_529_7()
// Bad code below
- (void)static_cast<Enum>((int*)0); // expected-error {{static_cast from 'int *' to 'enum Enum' is not allowed}}
+ (void)static_cast<Enum>((int*)0); // expected-error {{static_cast from 'int *' to 'Enum' is not allowed}}
}
// Void pointer to object pointer
@@ -129,8 +129,8 @@ void t_529_9()
(void)static_cast<int A::*>((int B::*)0);
// Bad code below
- (void)static_cast<int A::*>((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'struct H'}}
- (void)static_cast<int A::*>((int F::*)0); // expected-error {{conversion from pointer to member of class 'struct F'}}
+ (void)static_cast<int A::*>((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'H' to pointer to member of base class 'A':}}
+ (void)static_cast<int A::*>((int F::*)0); // expected-error {{conversion from pointer to member of class 'F' to pointer to member of class 'A' via virtual base 'B' is not allowed}}
}
// PR 5261 - static_cast should instantiate template if possible
@@ -181,3 +181,17 @@ struct X4 {
// PR5897 - accept static_cast from const void* to const int (*)[1].
void PR5897() { (void)static_cast<const int(*)[1]>((const void*)0); }
+
+namespace PR6072 {
+ struct A { };
+ struct B : A { void f(int); void f(); };
+ struct C : B { };
+ struct D { };
+
+ void f() {
+ (void)static_cast<void (A::*)()>(&B::f);
+ (void)static_cast<void (B::*)()>(&B::f);
+ (void)static_cast<void (C::*)()>(&B::f);
+ (void)static_cast<void (D::*)()>(&B::f); // expected-error{{static_cast from '<overloaded function type>' to 'void (PR6072::D::*)()' is not allowed}}
+ }
+}
diff --git a/test/SemaCXX/type-traits-incomplete.cpp b/test/SemaCXX/type-traits-incomplete.cpp
index 0ef6917..f959821 100644
--- a/test/SemaCXX/type-traits-incomplete.cpp
+++ b/test/SemaCXX/type-traits-incomplete.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-struct S; // expected-note{{forward declaration of 'struct S'}}
+struct S; // expected-note{{forward declaration of 'S'}}
void f() {
- __is_pod(S); // expected-error{{incomplete type 'struct S' used in type trait expression}}
+ __is_pod(S); // expected-error{{incomplete type 'S' used in type trait expression}}
}
diff --git a/test/SemaCXX/typedef-redecl.cpp b/test/SemaCXX/typedef-redecl.cpp
index 0d8dc84..c382539 100644
--- a/test/SemaCXX/typedef-redecl.cpp
+++ b/test/SemaCXX/typedef-redecl.cpp
@@ -11,10 +11,10 @@ struct X {
};
struct Y; // expected-note{{previous definition is here}}
-typedef int Y; // expected-error{{typedef redefinition with different types ('int' vs 'struct Y')}}
+typedef int Y; // expected-error{{typedef redefinition with different types ('int' vs 'Y')}}
typedef int Y2; // expected-note{{previous definition is here}}
-struct Y2; // expected-error{{definition of type 'struct Y2' conflicts with typedef of the same name}}
+struct Y2; // expected-error{{definition of type 'Y2' conflicts with typedef of the same name}}
void f(); // expected-note{{previous definition is here}}
typedef int f; // expected-error{{redefinition of 'f' as different kind of symbol}}
diff --git a/test/SemaCXX/typeid.cpp b/test/SemaCXX/typeid.cpp
index 7960cac..0e78ff4 100644
--- a/test/SemaCXX/typeid.cpp
+++ b/test/SemaCXX/typeid.cpp
@@ -18,7 +18,7 @@ void g()
struct X; // expected-note 3{{forward declaration}}
void g1(X &x) {
- (void)typeid(X); // expected-error{{'typeid' of incomplete type 'struct X'}}
- (void)typeid(X&); // expected-error{{'typeid' of incomplete type 'struct X'}}
- (void)typeid(x); // expected-error{{'typeid' of incomplete type 'struct X'}}
+ (void)typeid(X); // expected-error{{'typeid' of incomplete type 'X'}}
+ (void)typeid(X&); // expected-error{{'typeid' of incomplete type 'X'}}
+ (void)typeid(x); // expected-error{{'typeid' of incomplete type 'X'}}
}
diff --git a/test/SemaCXX/unknown-type-name.cpp b/test/SemaCXX/unknown-type-name.cpp
index 084a811..5f8d8ca 100644
--- a/test/SemaCXX/unknown-type-name.cpp
+++ b/test/SemaCXX/unknown-type-name.cpp
@@ -9,10 +9,10 @@ namespace N {
}
using namespace N;
-foo::bar x; // expected-error{{no type named 'bar' in 'struct N::Wibble'}}
+foo::bar x; // expected-error{{no type named 'bar' in 'N::Wibble'}}
void f() {
- foo::bar = 4; // expected-error{{no member named 'bar' in 'struct N::Wibble'}}
+ foo::bar = 4; // expected-error{{no member named 'bar' in 'N::Wibble'}}
}
template<typename T>
diff --git a/test/SemaCXX/using-decl-templates.cpp b/test/SemaCXX/using-decl-templates.cpp
index 8f2876c..5148ed5 100644
--- a/test/SemaCXX/using-decl-templates.cpp
+++ b/test/SemaCXX/using-decl-templates.cpp
@@ -13,7 +13,7 @@ template<typename T> struct B : A<T> {
using A<double>::f; // expected-error{{using declaration refers into 'A<double>::', which is not a base class of 'B<int>'}}
};
-B<int> a; // expected-note{{in instantiation of template class 'struct B<int>' requested here}}
+B<int> a; // expected-note{{in instantiation of template class 'B<int>' requested here}}
template<typename T> struct C : A<T> {
using A<T>::f;
diff --git a/test/SemaCXX/value-initialization.cpp b/test/SemaCXX/value-initialization.cpp
index d6a86c4..16a7a1d 100644
--- a/test/SemaCXX/value-initialization.cpp
+++ b/test/SemaCXX/value-initialization.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
-struct A { // expected-error {{implicit default constructor for 'struct A' must explicitly initialize the const member 'i'}}
+struct A { // expected-error {{implicit default constructor for 'A' must explicitly initialize the const member 'i'}}
const int i; // expected-note {{declared at}}
virtual void f() { }
};
diff --git a/test/SemaCXX/vararg-non-pod.cpp b/test/SemaCXX/vararg-non-pod.cpp
index 5f95446..d31f1f7 100644
--- a/test/SemaCXX/vararg-non-pod.cpp
+++ b/test/SemaCXX/vararg-non-pod.cpp
@@ -15,7 +15,7 @@ void t1()
{
C c(10);
- g(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic function; call will abort at runtime}}
+ g(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
g(10, version);
}
@@ -23,10 +23,10 @@ void t2()
{
C c(10);
- c.g(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic method; call will abort at runtime}}
+ c.g(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
c.g(10, version);
- C::h(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic function; call will abort at runtime}}
+ C::h(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic function; call will abort at runtime}}
C::h(10, version);
}
@@ -36,7 +36,7 @@ void t3()
{
C c(10);
- block(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic block; call will abort at runtime}}
+ block(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic block; call will abort at runtime}}
block(10, version);
}
@@ -51,7 +51,7 @@ void t4()
D d;
- d(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic method; call will abort at runtime}}
+ d(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
d(10, version);
}
@@ -63,8 +63,8 @@ void t5()
{
C c(10);
- E e(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic constructor; call will abort at runtime}}
- (void)E(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic constructor; call will abort at runtime}}
+ E e(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}}
+ (void)E(10, c); // expected-warning{{cannot pass object of non-POD type 'C' through variadic constructor; call will abort at runtime}}
}
// PR5761: unevaluated operands and the non-POD warning
@@ -85,6 +85,6 @@ Base &get_base(...);
int eat_base(...);
void test_typeid(Base &base) {
- (void)typeid(get_base(base)); // expected-warning{{cannot pass object of non-POD type 'struct Base' through variadic function; call will abort at runtime}}
+ (void)typeid(get_base(base)); // expected-warning{{cannot pass object of non-POD type 'Base' through variadic function; call will abort at runtime}}
(void)typeid(eat_base(base)); // okay
}
diff --git a/test/SemaCXX/vector-casts.cpp b/test/SemaCXX/vector-casts.cpp
index 6ee619e..4bb5808 100644
--- a/test/SemaCXX/vector-casts.cpp
+++ b/test/SemaCXX/vector-casts.cpp
@@ -22,10 +22,10 @@ void f() {
(void)reinterpret_cast<__v2si>(ll);
(void)(__v2si)(ll);
- (void)reinterpret_cast<S>(v2si); // expected-error {{reinterpret_cast from '__v2si' to 'struct S' is not allowed}}
- (void)(S)v2si; // expected-error {{C-style cast from '__v2si' to 'struct S' is not allowed}}
- (void)reinterpret_cast<__v2si>(s); // expected-error {{reinterpret_cast from 'struct S' to '__v2si' is not allowed}}
- (void)(__v2si)s; // expected-error {{C-style cast from 'struct S' to '__v2si' is not allowed}}
+ (void)reinterpret_cast<S>(v2si); // expected-error {{reinterpret_cast from '__v2si' to 'S' is not allowed}}
+ (void)(S)v2si; // expected-error {{C-style cast from '__v2si' to 'S' is not allowed}}
+ (void)reinterpret_cast<__v2si>(s); // expected-error {{reinterpret_cast from 'S' to '__v2si' is not allowed}}
+ (void)(__v2si)s; // expected-error {{C-style cast from 'S' to '__v2si' is not allowed}}
(void)reinterpret_cast<unsigned char>(v2si); // expected-error {{reinterpret_cast from vector '__v2si' to scalar 'unsigned char' of different size}}
(void)(unsigned char)v2si; // expected-error {{C-style cast from vector '__v2si' to scalar 'unsigned char' of different size}}
diff --git a/test/SemaCXX/virtual-member-functions-key-function.cpp b/test/SemaCXX/virtual-member-functions-key-function.cpp
index 2e21fb7..97164d9 100644
--- a/test/SemaCXX/virtual-member-functions-key-function.cpp
+++ b/test/SemaCXX/virtual-member-functions-key-function.cpp
@@ -6,11 +6,11 @@ struct A {
struct B : A { // expected-error {{no suitable member 'operator delete' in 'B'}}
B() { }
void operator delete(void *, int); // expected-note {{'operator delete' declared here}}
-}; // expected-note {{implicit default destructor for 'struct B' first required here}}
+}; // expected-note {{implicit default destructor for 'B' first required here}}
struct C : A { // expected-error {{no suitable member 'operator delete' in 'C'}}
void operator delete(void *, int); // expected-note {{'operator delete' declared here}}
-}; // expected-note {{implicit default destructor for 'struct C' first required here}}
+}; // expected-note {{implicit default destructor for 'C' first required here}}
void f() {
(void)new B;
diff --git a/test/SemaCXX/virtual-override.cpp b/test/SemaCXX/virtual-override.cpp
index 09cbfad..6887135 100644
--- a/test/SemaCXX/virtual-override.cpp
+++ b/test/SemaCXX/virtual-override.cpp
@@ -21,7 +21,7 @@ class A {
};
class B : A {
- virtual b* f(); // expected-error{{return type of virtual function 'f' is not covariant with the return type of the function it overrides ('struct T2::b *' is not derived from 'struct T2::a *')}}
+ virtual b* f(); // expected-error{{return type of virtual function 'f' is not covariant with the return type of the function it overrides ('T2::b *' is not derived from 'T2::a *')}}
};
}
@@ -36,7 +36,7 @@ class A {
};
class B : A {
- virtual b* f(); // expected-error{{invalid covariant return for virtual function: 'struct T3::a' is a private base class of 'struct T3::b'}}
+ virtual b* f(); // expected-error{{invalid covariant return for virtual function: 'T3::a' is a private base class of 'T3::b'}}
};
}
@@ -52,7 +52,7 @@ class A {
};
class B : A {
- virtual b* f(); // expected-error{{return type of virtual function 'f' is not covariant with the return type of the function it overrides (ambiguous conversion from derived class 'struct T4::b' to base class 'struct T4::a':\n\
+ virtual b* f(); // expected-error{{return type of virtual function 'f' is not covariant with the return type of the function it overrides (ambiguous conversion from derived class 'T4::b' to base class 'T4::a':\n\
struct T4::b -> struct T4::a\n\
struct T4::b -> struct T4::a1 -> struct T4::a)}}
};
@@ -70,7 +70,7 @@ class A {
class B : A {
virtual a* const f();
- virtual a* g(); // expected-error{{return type of virtual function 'g' is not covariant with the return type of the function it overrides ('struct T5::a *' has different qualifiers than 'struct T5::a *const')}}
+ virtual a* g(); // expected-error{{return type of virtual function 'g' is not covariant with the return type of the function it overrides ('T5::a *' has different qualifiers than 'T5::a *const')}}
};
}
@@ -86,7 +86,7 @@ class A {
class B : A {
virtual a* f();
- virtual const a* g(); // expected-error{{return type of virtual function 'g' is not covariant with the return type of the function it overrides (class type 'struct T6::a const *' is more qualified than class type 'struct T6::a *'}}
+ virtual const a* g(); // expected-error{{return type of virtual function 'g' is not covariant with the return type of the function it overrides (class type 'T6::a const *' is more qualified than class type 'T6::a *'}}
};
}
@@ -106,14 +106,14 @@ namespace T7 {
namespace T8 {
struct a { };
- struct b; // expected-note {{forward declaration of 'struct T8::b'}}
+ struct b; // expected-note {{forward declaration of 'T8::b'}}
class A {
virtual a *f();
};
class B : A {
- b* f(); // expected-error {{return type of virtual function 'f' is not covariant with the return type of the function it overrides ('struct T8::b' is incomplete)}}
+ b* f(); // expected-error {{return type of virtual function 'f' is not covariant with the return type of the function it overrides ('T8::b' is incomplete)}}
};
}
@@ -129,7 +129,7 @@ namespace T9 {
};
class B : A {
- virtual b<int> *f(); // expected-note {{in instantiation of template class 'struct T9::b<int>' requested here}}
+ virtual b<int> *f(); // expected-note {{in instantiation of template class 'T9::b<int>' requested here}}
};
}
@@ -230,7 +230,7 @@ namespace type_dependent_covariance {
};
template <int N, int M> struct X1 : X<N> {
virtual TD<M>* f1(); // expected-error{{return type of virtual function 'f1' is not covariant with the return type of the function it overrides ('TD<1> *'}}
- virtual D* f2(); // expected-error{{return type of virtual function 'f2' is not covariant with the return type of the function it overrides ('struct type_dependent_covariance::D *' is not derived from 'TB<1> *')}}
+ virtual D* f2(); // expected-error{{return type of virtual function 'f2' is not covariant with the return type of the function it overrides ('type_dependent_covariance::D *' is not derived from 'TB<1> *')}}
};
X1<0, 0> good;
@@ -260,7 +260,7 @@ namespace T11 {
};
struct D : C {
- virtual B&& f(); // expected-error {{virtual function 'f' has a different return type ('struct T11::B &&') than the function it overrides (which has return type 'struct T11::A &')}}
+ virtual B&& f(); // expected-error {{virtual function 'f' has a different return type ('T11::B &&') than the function it overrides (which has return type 'T11::A &')}}
};
};
@@ -273,6 +273,6 @@ namespace T12 {
};
struct D : C {
- virtual B& f(); // expected-error {{virtual function 'f' has a different return type ('struct T12::B &') than the function it overrides (which has return type 'struct T12::A &&')}}
+ virtual B& f(); // expected-error {{virtual function 'f' has a different return type ('T12::B &') than the function it overrides (which has return type 'T12::A &&')}}
};
};
diff --git a/test/SemaCXX/warn-reorder-ctor-initialization.cpp b/test/SemaCXX/warn-reorder-ctor-initialization.cpp
index 35b32b2..2634202 100644
--- a/test/SemaCXX/warn-reorder-ctor-initialization.cpp
+++ b/test/SemaCXX/warn-reorder-ctor-initialization.cpp
@@ -9,9 +9,9 @@ public:
complex() : s2(1), // expected-warning {{member 's2' will be initialized after}}
s1(1) , // expected-note {{field s1}}
s3(3), // expected-warning {{member 's3' will be initialized after}}
- BB1(), // expected-note {{base 'struct BB1'}} \
- // expected-warning {{base class 'struct BB1' will be initialized after}}
- BB() {} // expected-note {{base 'struct BB'}}
+ BB1(), // expected-note {{base 'BB1'}} \
+ // expected-warning {{base class 'BB1' will be initialized after}}
+ BB() {} // expected-note {{base 'BB'}}
int s1;
int s2;
int s3;
@@ -44,14 +44,14 @@ struct C : public A, public B, private virtual V {
struct D : public A, public B {
- D() : A(), V() { } // expected-warning {{base class 'struct A' will be initialized after}} \
- // expected-note {{base 'struct V'}}
+ D() : A(), V() { } // expected-warning {{base class 'A' will be initialized after}} \
+ // expected-note {{base 'V'}}
};
struct E : public A, public B, private virtual V {
- E() : A(), V() { } // expected-warning {{base class 'struct A' will be initialized after}} \
- // expected-note {{base 'struct V'}}
+ E() : A(), V() { } // expected-warning {{base class 'A' will be initialized after}} \
+ // expected-note {{base 'V'}}
};
@@ -64,13 +64,13 @@ struct B1 {
};
struct F : public A1, public B1, private virtual V {
- F() : A1(), V() { } // expected-warning {{base class 'struct A1' will be initialized after}} \
- // expected-note {{base 'struct V'}}
+ F() : A1(), V() { } // expected-warning {{base class 'A1' will be initialized after}} \
+ // expected-note {{base 'V'}}
};
struct X : public virtual A, virtual V, public virtual B {
- X(): A(), V(), B() {} // expected-warning {{base class 'struct A' will be initialized after}} \
- // expected-note {{base 'struct V'}}
+ X(): A(), V(), B() {} // expected-warning {{base class 'A' will be initialized after}} \
+ // expected-note {{base 'V'}}
};
class Anon {
diff --git a/test/SemaObjC/blocks.m b/test/SemaObjC/blocks.m
index 3629230..ddac7d1 100644
--- a/test/SemaObjC/blocks.m
+++ b/test/SemaObjC/blocks.m
@@ -55,3 +55,15 @@ int foo9() {
}
}
+
+// rdar 7725203
+@class NSString;
+
+extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2)));
+
+void foo10() {
+ void(^myBlock)(void) = ^{
+ };
+ NSLog(@"%@", myBlock);
+}
+
diff --git a/test/SemaObjC/exprs.m b/test/SemaObjC/exprs.m
index 33b1444..3370bda 100644
--- a/test/SemaObjC/exprs.m
+++ b/test/SemaObjC/exprs.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify -Wno-unreachable-code
+// RUN: %clang_cc1 %s -fsyntax-only -fblocks -verify -Wno-unreachable-code
// rdar://6597252
Class test1(Class X) {
@@ -19,3 +19,6 @@ void test2() {
if (@encode(int) == "foo") { } // expected-warning {{result of comparison against @encode is unspecified}}
}
+
+#define MAX(A,B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __b : __a; })
+void (^foo)(int, int) = ^(int x, int y) { int z = MAX(x, y); };
diff --git a/test/SemaObjCXX/cstyle-cast.mm b/test/SemaObjCXX/cstyle-cast.mm
index 4a211e3..c4b176c 100644
--- a/test/SemaObjCXX/cstyle-cast.mm
+++ b/test/SemaObjCXX/cstyle-cast.mm
@@ -18,7 +18,7 @@ void test1(X x) {
I<P> *ip = (I<P>*)cft;
- (id)x; // expected-error {{C-style cast from 'struct X' to 'id' is not allowed}}
+ (id)x; // expected-error {{C-style cast from 'X' to 'id' is not allowed}}
id *pid = (id*)ccct;
diff --git a/test/SemaObjCXX/vararg-non-pod.mm b/test/SemaObjCXX/vararg-non-pod.mm
index 6ced8e4..7e5c4c6 100644
--- a/test/SemaObjCXX/vararg-non-pod.mm
+++ b/test/SemaObjCXX/vararg-non-pod.mm
@@ -17,7 +17,7 @@ void t1(D *d)
{
C c(10);
- [d g:10, c]; // expected-warning{{cannot pass object of non-POD type 'class C' through variadic method; call will abort at runtime}}
+ [d g:10, c]; // expected-warning{{cannot pass object of non-POD type 'C' through variadic method; call will abort at runtime}}
[d g:10, version];
}
diff --git a/test/SemaTemplate/class-template-id-2.cpp b/test/SemaTemplate/class-template-id-2.cpp
index c492a36..d09f524 100644
--- a/test/SemaTemplate/class-template-id-2.cpp
+++ b/test/SemaTemplate/class-template-id-2.cpp
@@ -4,7 +4,7 @@ namespace N {
template<> class A<int> { };
- template<> class A<float>; // expected-note{{forward declaration of 'class N::A<float>'}}
+ template<> class A<float>; // expected-note{{forward declaration of 'N::A<float>'}}
class B : public A<int> { };
}
diff --git a/test/SemaTemplate/class-template-spec.cpp b/test/SemaTemplate/class-template-spec.cpp
index efb00c7..c65802e 100644
--- a/test/SemaTemplate/class-template-spec.cpp
+++ b/test/SemaTemplate/class-template-spec.cpp
@@ -20,7 +20,7 @@ int test_incomplete_specs(A<double, double> *a1,
A<double> *a2)
{
(void)a1->x; // expected-error{{member access into incomplete type}}
- (void)a2->x; // expected-error{{implicit instantiation of undefined template 'struct A<double, int>'}}
+ (void)a2->x; // expected-error{{implicit instantiation of undefined template 'A<double, int>'}}
}
typedef float FLOAT;
diff --git a/test/SemaTemplate/default-expr-arguments.cpp b/test/SemaTemplate/default-expr-arguments.cpp
index 3da43fa..d2cc45b 100644
--- a/test/SemaTemplate/default-expr-arguments.cpp
+++ b/test/SemaTemplate/default-expr-arguments.cpp
@@ -11,17 +11,17 @@ template<typename T> void f1(T a, T b = 10) { } // expected-error{{no viable con
template<typename T> void f2(T a, T b = T()) { }
-template<typename T> void f3(T a, T b = T() + T()); // expected-error{{invalid operands to binary expression ('struct S' and 'struct S')}}
+template<typename T> void f3(T a, T b = T() + T()); // expected-error{{invalid operands to binary expression ('S' and 'S')}}
void g() {
f1(10);
- f1(S()); // expected-note{{in instantiation of default function argument expression for 'f1<struct S>' required here}}
+ f1(S()); // expected-note{{in instantiation of default function argument expression for 'f1<S>' required here}}
f2(10);
f2(S());
f3(10);
- f3(S()); // expected-note{{in instantiation of default function argument expression for 'f3<struct S>' required here}}
+ f3(S()); // expected-note{{in instantiation of default function argument expression for 'f3<S>' required here}}
}
template<typename T> struct F {
@@ -38,10 +38,10 @@ void g2() {
void g3(F<int> f, F<struct S> s) {
f.f();
- s.f(); // expected-note{{in instantiation of default function argument expression for 'f<struct S>' required here}}
+ s.f(); // expected-note{{in instantiation of default function argument expression for 'f<S>' required here}}
F<int> f2;
- F<S> s2; // expected-note{{in instantiation of default function argument expression for 'F<struct S>' required here}}
+ F<S> s2; // expected-note{{in instantiation of default function argument expression for 'F<S>' required here}}
}
template<typename T> struct G {
diff --git a/test/SemaTemplate/dependent-base-classes.cpp b/test/SemaTemplate/dependent-base-classes.cpp
index 08d4de5..600115b 100644
--- a/test/SemaTemplate/dependent-base-classes.cpp
+++ b/test/SemaTemplate/dependent-base-classes.cpp
@@ -32,7 +32,7 @@ namespace PR6031 {
template <class TT>
struct FI2
{
- C<typename FI2::type> a; // expected-error{{no type named 'type' in 'struct PR6031::FI2'}} \
+ C<typename FI2::type> a; // expected-error{{no type named 'type' in 'FI2<TT>'}} \
// expected-error{{C++ requires a type specifier for all declarations}}
};
@@ -58,7 +58,7 @@ namespace PR6031 {
class NoDepBase::Nested nested; // expected-error{{'Nested' does not name a tag member in the specified scope}}
typedef typename NoDepBase::template MemberTemplate<T>::type type; // expected-error{{'MemberTemplate' following the 'template' keyword does not refer to a template}} \
// FIXME: expected-error{{unqualified-id}}
- return NoDepBase::a; // expected-error{{no member named 'a' in 'struct PR6031::NoDepBase'}}
+ return NoDepBase::a; // expected-error{{no member named 'a' in 'NoDepBase<T>'}}
}
};
}
diff --git a/test/SemaTemplate/ext-vector-type.cpp b/test/SemaTemplate/ext-vector-type.cpp
index 0e2debf..3973102 100644
--- a/test/SemaTemplate/ext-vector-type.cpp
+++ b/test/SemaTemplate/ext-vector-type.cpp
@@ -20,7 +20,7 @@ int test_make2() {
template<typename T, unsigned Length>
struct make3 {
- typedef T __attribute__((ext_vector_type(Length))) type; // expected-error{{invalid vector type 'struct s'}}
+ typedef T __attribute__((ext_vector_type(Length))) type; // expected-error{{invalid vector type 's'}}
};
struct s {};
diff --git a/test/SemaTemplate/injected-class-name.cpp b/test/SemaTemplate/injected-class-name.cpp
index 482eae1..586be18 100644
--- a/test/SemaTemplate/injected-class-name.cpp
+++ b/test/SemaTemplate/injected-class-name.cpp
@@ -42,3 +42,9 @@ struct X1 {
void f0(const X1<T, N>&); // expected-error{{redecl}}
};
+namespace pr6326 {
+ template <class T> class A {
+ friend class A;
+ };
+ template class A<int>;
+}
diff --git a/test/SemaTemplate/instantiate-cast.cpp b/test/SemaTemplate/instantiate-cast.cpp
index 97d3dc3..9669b20 100644
--- a/test/SemaTemplate/instantiate-cast.cpp
+++ b/test/SemaTemplate/instantiate-cast.cpp
@@ -23,7 +23,7 @@ struct Constructible {
template<typename T, typename U>
struct CStyleCast0 {
void f(T t) {
- (void)((U)t); // expected-error{{C-style cast from 'struct A' to 'int'}}
+ (void)((U)t); // expected-error{{C-style cast from 'A' to 'int' is not allowed}}
}
};
@@ -36,7 +36,7 @@ template struct CStyleCast0<A, int>; // expected-note{{instantiation}}
template<typename T, typename U>
struct StaticCast0 {
void f(T t) {
- (void)static_cast<U>(t); // expected-error{{static_cast from 'int' to 'struct A' is not allowed}}
+ (void)static_cast<U>(t); // expected-error{{static_cast from 'int' to 'A' is not allowed}}
}
};
@@ -89,7 +89,7 @@ template struct ConstCast0<int const *, float *>; // expected-note{{instantiatio
template<typename T, typename U>
struct FunctionalCast1 {
void f(T t) {
- (void)U(t); // expected-error{{functional-style cast from 'struct A' to 'int'}}
+ (void)U(t); // expected-error{{functional-style cast from 'A' to 'int' is not allowed}}
}
};
diff --git a/test/SemaTemplate/instantiate-complete.cpp b/test/SemaTemplate/instantiate-complete.cpp
index 0ae13b9..82cc320 100644
--- a/test/SemaTemplate/instantiate-complete.cpp
+++ b/test/SemaTemplate/instantiate-complete.cpp
@@ -17,12 +17,12 @@ struct X {
X<int> f() { return 0; }
struct XField {
- X<float(int)> xf; // expected-note{{in instantiation of template class 'struct X<float (int)>' requested here}}
+ X<float(int)> xf; // expected-note{{in instantiation of template class 'X<float (int)>' requested here}}
};
void test_subscript(X<double> *ptr1, X<int(int)> *ptr2, int i) {
(void)ptr1[i];
- (void)ptr2[i]; // expected-note{{in instantiation of template class 'struct X<int (int)>' requested here}}
+ (void)ptr2[i]; // expected-note{{in instantiation of template class 'X<int (int)>' requested here}}
}
void test_arith(X<signed char> *ptr1, X<unsigned char> *ptr2,
@@ -30,13 +30,13 @@ void test_arith(X<signed char> *ptr1, X<unsigned char> *ptr2,
(void)(ptr1 + 5);
// FIXME: if I drop the ')' after void, below, it still parses (!)
(void)(5 + ptr2);
- (void)(ptr3 + 5); // expected-note{{in instantiation of template class 'struct X<char (char)>' requested here}}
- (void)(5 + ptr4); // expected-note{{in instantiation of template class 'struct X<short (short)>' requested here}}
+ (void)(ptr3 + 5); // expected-note{{in instantiation of template class 'X<char (char)>' requested here}}
+ (void)(5 + ptr4); // expected-note{{in instantiation of template class 'X<short (short)>' requested here}}
}
void test_new() {
(void)new X<float>(0);
- (void)new X<float(float)>; // expected-note{{in instantiation of template class 'struct X<float (float)>' requested here}}
+ (void)new X<float(float)>; // expected-note{{in instantiation of template class 'X<float (float)>' requested here}}
}
void test_memptr(X<long> *p1, long X<long>::*pm1,
diff --git a/test/SemaTemplate/instantiate-exception-spec.cpp b/test/SemaTemplate/instantiate-exception-spec.cpp
index c418fe1..d4f12df 100644
--- a/test/SemaTemplate/instantiate-exception-spec.cpp
+++ b/test/SemaTemplate/instantiate-exception-spec.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
// FIXME: the "note" should be down at the call site!
-template<typename T> void f1(T*) throw(T); // expected-error{{incomplete type 'struct Incomplete' is not allowed in exception specification}} \
+template<typename T> void f1(T*) throw(T); // expected-error{{incomplete type 'Incomplete' is not allowed in exception specification}} \
// expected-note{{instantiation of}}
struct Incomplete; // expected-note{{forward}}
diff --git a/test/SemaTemplate/instantiate-expr-1.cpp b/test/SemaTemplate/instantiate-expr-1.cpp
index 37145b6..7af59fd 100644
--- a/test/SemaTemplate/instantiate-expr-1.cpp
+++ b/test/SemaTemplate/instantiate-expr-1.cpp
@@ -7,7 +7,7 @@ struct Bitfields {
void test_Bitfields(Bitfields<0, 5> *b) {
(void)sizeof(Bitfields<10, 5>);
- (void)sizeof(Bitfields<0, 1>); // expected-note{{in instantiation of template class 'struct Bitfields<0, 1>' requested here}}
+ (void)sizeof(Bitfields<0, 1>); // expected-note{{in instantiation of template class 'Bitfields<0, 1>' requested here}}
}
template<int I, int J>
@@ -17,7 +17,7 @@ struct BitfieldPlus {
void test_BitfieldPlus() {
(void)sizeof(BitfieldPlus<0, 1>);
- (void)sizeof(BitfieldPlus<-5, 5>); // expected-note{{in instantiation of template class 'struct BitfieldPlus<-5, 5>' requested here}}
+ (void)sizeof(BitfieldPlus<-5, 5>); // expected-note{{in instantiation of template class 'BitfieldPlus<-5, 5>' requested here}}
}
template<int I, int J>
@@ -28,8 +28,8 @@ struct BitfieldMinus {
void test_BitfieldMinus() {
(void)sizeof(BitfieldMinus<5, 1>);
- (void)sizeof(BitfieldMinus<0, 1>); // expected-note{{in instantiation of template class 'struct BitfieldMinus<0, 1>' requested here}}
- (void)sizeof(BitfieldMinus<5, 5>); // expected-note{{in instantiation of template class 'struct BitfieldMinus<5, 5>' requested here}}
+ (void)sizeof(BitfieldMinus<0, 1>); // expected-note{{in instantiation of template class 'BitfieldMinus<0, 1>' requested here}}
+ (void)sizeof(BitfieldMinus<5, 5>); // expected-note{{in instantiation of template class 'BitfieldMinus<5, 5>' requested here}}
}
template<int I, int J>
@@ -40,7 +40,7 @@ struct BitfieldDivide {
void test_BitfieldDivide() {
(void)sizeof(BitfieldDivide<5, 1>);
- (void)sizeof(BitfieldDivide<5, 0>); // expected-note{{in instantiation of template class 'struct BitfieldDivide<5, 0>' requested here}}
+ (void)sizeof(BitfieldDivide<5, 0>); // expected-note{{in instantiation of template class 'BitfieldDivide<5, 0>' requested here}}
}
template<typename T, T I, int J>
@@ -64,9 +64,9 @@ struct BitfieldNeg2 {
void test_BitfieldNeg() {
(void)sizeof(BitfieldNeg<-5>); // okay
- (void)sizeof(BitfieldNeg<5>); // expected-note{{in instantiation of template class 'struct BitfieldNeg<5>' requested here}}
+ (void)sizeof(BitfieldNeg<5>); // expected-note{{in instantiation of template class 'BitfieldNeg<5>' requested here}}
(void)sizeof(BitfieldNeg2<int, -5>); // okay
- (void)sizeof(BitfieldNeg2<int, 5>); // expected-note{{in instantiation of template class 'struct BitfieldNeg2<int, 5>' requested here}}
+ (void)sizeof(BitfieldNeg2<int, 5>); // expected-note{{in instantiation of template class 'BitfieldNeg2<int, 5>' requested here}}
}
template<typename T>
diff --git a/test/SemaTemplate/instantiate-expr-4.cpp b/test/SemaTemplate/instantiate-expr-4.cpp
index c5eb3cc..92915c7 100644
--- a/test/SemaTemplate/instantiate-expr-4.cpp
+++ b/test/SemaTemplate/instantiate-expr-4.cpp
@@ -153,7 +153,7 @@ struct TypeId0 {
if (ptr)
return typeid(ptr);
else
- return typeid(T); // expected-error{{'typeid' of incomplete type 'struct Incomplete'}}
+ return typeid(T); // expected-error{{'typeid' of incomplete type 'Incomplete'}}
}
};
diff --git a/test/SemaTemplate/instantiate-field.cpp b/test/SemaTemplate/instantiate-field.cpp
index d166e7e..60d4b21 100644
--- a/test/SemaTemplate/instantiate-field.cpp
+++ b/test/SemaTemplate/instantiate-field.cpp
@@ -20,9 +20,9 @@ void test1(const X<int> *xi) {
}
void test2(const X<float> *xf) {
- (void)xf->x; // expected-note{{in instantiation of template class 'struct X<float>' requested here}}
+ (void)xf->x; // expected-note{{in instantiation of template class 'X<float>' requested here}}
}
void test3(const X<int(int)> *xf) {
- (void)xf->x; // expected-note{{in instantiation of template class 'struct X<int (int)>' requested here}}
+ (void)xf->x; // expected-note{{in instantiation of template class 'X<int (int)>' requested here}}
}
diff --git a/test/SemaTemplate/instantiate-function-1.cpp b/test/SemaTemplate/instantiate-function-1.cpp
index 144c630..7b4c53c 100644
--- a/test/SemaTemplate/instantiate-function-1.cpp
+++ b/test/SemaTemplate/instantiate-function-1.cpp
@@ -194,7 +194,7 @@ template struct IndirectGoto0<int>; // expected-note{{instantiation}}
template<typename T> struct TryCatch0 {
void f() {
try {
- } catch (T t) { // expected-error{{incomplete type}} \
+ } catch (T t) { // expected-warning{{incomplete type}} \
// expected-error{{abstract class}}
} catch (...) {
}
diff --git a/test/SemaTemplate/instantiate-member-class.cpp b/test/SemaTemplate/instantiate-member-class.cpp
index 742abcc..5d69b50 100644
--- a/test/SemaTemplate/instantiate-member-class.cpp
+++ b/test/SemaTemplate/instantiate-member-class.cpp
@@ -28,14 +28,14 @@ void test_instantiation(X<double>::C *x,
X<float>::D::F *f) {
double &dr = x->foo();
float &fr = e->bar();
- f->foo(); // expected-error{{implicit instantiation of undefined member 'struct X<float>::D::F'}}
+ f->foo(); // expected-error{{implicit instantiation of undefined member 'X<float>::D::F'}}
}
X<void>::C *c3; // okay
X<void>::D::E *e1; // okay
-X<void>::D::E e2; // expected-note{{in instantiation of member class 'struct X<void>::D::E' requested here}}
+X<void>::D::E e2; // expected-note{{in instantiation of member class 'X<void>::D::E' requested here}}
// Redeclarations.
namespace test1 {
diff --git a/test/SemaTemplate/instantiate-member-expr.cpp b/test/SemaTemplate/instantiate-member-expr.cpp
index 324363c..f3a6067 100644
--- a/test/SemaTemplate/instantiate-member-expr.cpp
+++ b/test/SemaTemplate/instantiate-member-expr.cpp
@@ -16,14 +16,14 @@ public:
template <typename CHECKER>
void registerCheck(CHECKER *check) {
- Checkers.push_back(S<void *>()); // expected-note {{in instantiation of member function 'vector<struct S<void *> >::push_back' requested here}}
+ Checkers.push_back(S<void *>()); // expected-note {{in instantiation of member function 'vector<S<void *> >::push_back' requested here}}
}
};
class RetainReleaseChecker { };
void f(GRExprEngine& Eng) {
- Eng.registerCheck(new RetainReleaseChecker); // expected-note {{in instantiation of function template specialization 'GRExprEngine::registerCheck<class RetainReleaseChecker>' requested here}}
+ Eng.registerCheck(new RetainReleaseChecker); // expected-note {{in instantiation of function template specialization 'GRExprEngine::registerCheck<RetainReleaseChecker>' requested here}}
}
// PR 5838
@@ -43,7 +43,7 @@ namespace test1 {
int a;
template<typename T> struct B : A<T> {
void f() {
- a = 0; // expected-error {{type 'struct test1::O' is not a direct or virtual base of ''B<int>''}}
+ a = 0; // expected-error {{type 'test1::O' is not a direct or virtual base of ''B<int>''}}
}
};
};
diff --git a/test/SemaTemplate/instantiate-method.cpp b/test/SemaTemplate/instantiate-method.cpp
index a02fe52..357ea26 100644
--- a/test/SemaTemplate/instantiate-method.cpp
+++ b/test/SemaTemplate/instantiate-method.cpp
@@ -20,7 +20,7 @@ void test(X<int> *xi, int *ip, X<int(int)> *xf) {
}
void test_bad() {
- X<void> xv; // expected-note{{in instantiation of template class 'class X<void>' requested here}}
+ X<void> xv; // expected-note{{in instantiation of template class 'X<void>' requested here}}
}
template<typename T, typename U>
@@ -36,7 +36,7 @@ void test_ovl(Overloading<int, long> *oil, int i, long l) {
}
void test_ovl_bad() {
- Overloading<float, float> off; // expected-note{{in instantiation of template class 'class Overloading<float, float>' requested here}}
+ Overloading<float, float> off; // expected-note{{in instantiation of template class 'Overloading<float, float>' requested here}}
}
template<typename T>
diff --git a/test/SemaTemplate/instantiate-static-var.cpp b/test/SemaTemplate/instantiate-static-var.cpp
index fda2b9ea..e90ac52 100644
--- a/test/SemaTemplate/instantiate-static-var.cpp
+++ b/test/SemaTemplate/instantiate-static-var.cpp
@@ -6,7 +6,7 @@ public:
};
int array1[X<int, 2>::value == 5? 1 : -1];
-X<int, 0> xi0; // expected-note{{in instantiation of template class 'class X<int, 0>' requested here}}
+X<int, 0> xi0; // expected-note{{in instantiation of template class 'X<int, 0>' requested here}}
template<typename T>
@@ -14,7 +14,7 @@ class Y {
static const T value = 0; // expected-error{{'value' can only be initialized if it is a static const integral data member}}
};
-Y<float> fy; // expected-note{{in instantiation of template class 'class Y<float>' requested here}}
+Y<float> fy; // expected-note{{in instantiation of template class 'Y<float>' requested here}}
// out-of-line static member variables
diff --git a/test/SemaTemplate/instantiate-typedef.cpp b/test/SemaTemplate/instantiate-typedef.cpp
index 977fd08..bb168a1 100644
--- a/test/SemaTemplate/instantiate-typedef.cpp
+++ b/test/SemaTemplate/instantiate-typedef.cpp
@@ -11,6 +11,6 @@ add_pointer<float>::type test2(int * ptr) {
return ptr; // expected-error{{cannot initialize return object of type 'add_pointer<float>::type' (aka 'float *') with an lvalue of type 'int *'}}
}
-add_pointer<int&>::type // expected-note{{in instantiation of template class 'struct add_pointer<int &>' requested here}} \
-// expected-error {{no type named 'type' in 'struct add_pointer<int &>'}}
+add_pointer<int&>::type // expected-note{{in instantiation of template class 'add_pointer<int &>' requested here}} \
+// expected-error {{no type named 'type' in 'add_pointer<int &>'}}
test3();
diff --git a/test/SemaTemplate/instantiation-backtrace.cpp b/test/SemaTemplate/instantiation-backtrace.cpp
index 93f9a35..21456e9 100644
--- a/test/SemaTemplate/instantiation-backtrace.cpp
+++ b/test/SemaTemplate/instantiation-backtrace.cpp
@@ -2,7 +2,7 @@
template<typename T> struct A; // expected-note 4{{template is declared here}}
template<typename T> struct B : A<T*> { }; // expected-error{{implicit instantiation of undefined template}} \
-// expected-error{{implicit instantiation of undefined template 'struct A<X *>'}}
+// expected-error{{implicit instantiation of undefined template 'A<X *>'}}
template<typename T> struct C : B<T> { } ; // expected-note{{instantiation of template class}}
@@ -19,14 +19,14 @@ void f() {
typedef struct { } X;
void g() {
- (void)sizeof(B<X>); // expected-note{{in instantiation of template class 'struct B<X>' requested here}}
+ (void)sizeof(B<X>); // expected-note{{in instantiation of template class 'B<X>' requested here}}
}
template<typename T>
-struct G : A<T>, // expected-error{{implicit instantiation of undefined template 'struct A<int>'}}
- A<T*> // expected-error{{implicit instantiation of undefined template 'struct A<int *>'}}
+struct G : A<T>, // expected-error{{implicit instantiation of undefined template 'A<int>'}}
+ A<T*> // expected-error{{implicit instantiation of undefined template 'A<int *>'}}
{ };
void h() {
- (void)sizeof(G<int>); // expected-note{{in instantiation of template class 'struct G<int>' requested here}}
+ (void)sizeof(G<int>); // expected-note{{in instantiation of template class 'G<int>' requested here}}
}
diff --git a/test/SemaTemplate/metafun-apply.cpp b/test/SemaTemplate/metafun-apply.cpp
index bb3c88a..3a7408e 100644
--- a/test/SemaTemplate/metafun-apply.cpp
+++ b/test/SemaTemplate/metafun-apply.cpp
@@ -22,7 +22,7 @@ struct bogus {
template<typename MetaFun, typename T>
struct apply1 {
- typedef typename MetaFun::template apply<T>::type type; // expected-note{{in instantiation of template class 'struct add_reference::apply<void>' requested here}} \
+ typedef typename MetaFun::template apply<T>::type type; // expected-note{{in instantiation of template class 'add_reference::apply<void>' requested here}} \
// expected-error{{'apply' following the 'template' keyword does not refer to a template}}
};
@@ -32,9 +32,9 @@ apply1<add_reference, int>::type ir = i;
apply1<add_reference, float>::type fr = i; // expected-error{{non-const lvalue reference to type 'float' cannot bind to a value of unrelated type 'int'}}
void test() {
- apply1<add_reference, void>::type t; // expected-note{{in instantiation of template class 'struct apply1<struct add_reference, void>' requested here}}
+ apply1<add_reference, void>::type t; // expected-note{{in instantiation of template class 'apply1<add_reference, void>' requested here}}
- apply1<bogus, int>::type t2; // expected-note{{in instantiation of template class 'struct apply1<struct bogus, int>' requested here}}
+ apply1<bogus, int>::type t2; // expected-note{{in instantiation of template class 'apply1<bogus, int>' requested here}}
}
diff --git a/test/SemaTemplate/temp_arg_nontype.cpp b/test/SemaTemplate/temp_arg_nontype.cpp
index fdfd4e4..9c20f2a 100644
--- a/test/SemaTemplate/temp_arg_nontype.cpp
+++ b/test/SemaTemplate/temp_arg_nontype.cpp
@@ -16,7 +16,7 @@ enum E { Enumerator = 17 };
A<E> *a5; // expected-error{{template argument for non-type template parameter must be an expression}}
template<E Value> struct A1; // expected-note{{template parameter is declared here}}
A1<Enumerator> *a6; // okay
-A1<17> *a7; // expected-error{{non-type template argument of type 'int' cannot be converted to a value of type 'enum E'}}
+A1<17> *a7; // expected-error{{non-type template argument of type 'int' cannot be converted to a value of type 'E'}}
const long LongValue = 12345678;
A<LongValue> *a8;
@@ -32,7 +32,7 @@ public:
X(int, int);
operator int() const;
};
-A<X(17, 42)> *a11; // expected-error{{non-type template argument of type 'class X' must have an integral or enumeration type}}
+A<X(17, 42)> *a11; // expected-error{{non-type template argument of type 'X' must have an integral or enumeration type}}
float f(float);
@@ -59,8 +59,8 @@ volatile X * X_volatile_ptr;
template<X const &AnX> struct A4; // expected-note 2{{template parameter is declared here}}
X an_X;
A4<an_X> *a15_1; // okay
-A4<*X_volatile_ptr> *a15_2; // expected-error{{reference binding of non-type template parameter of type 'class X const &' to template argument of type 'class X volatile' ignores qualifiers}}
-A4<y> *15_3; // expected-error{{non-type template parameter of reference type 'class X const &' cannot bind to template argument of type 'struct Y'}} \
+A4<*X_volatile_ptr> *a15_2; // expected-error{{reference binding of non-type template parameter of type 'X const &' to template argument of type 'X volatile' ignores qualifiers}}
+A4<y> *15_3; // expected-error{{non-type template parameter of reference type 'X const &' cannot bind to template argument of type 'struct Y'}} \
// FIXME: expected-error{{expected unqualified-id}}
template<int (&fr)(int)> struct A5; // expected-note 2{{template parameter is declared here}}
@@ -83,14 +83,14 @@ struct Z {
template<int (Z::*pmf)(int)> struct A6; // expected-note{{template parameter is declared here}}
A6<&Z::foo> *a17_1;
A6<&Z::bar> *a17_2;
-A6<&Z::baz> *a17_3; // expected-error{{non-type template argument of type 'double (struct Z::*)(double)' cannot be converted to a value of type 'int (struct Z::*)(int)'}}
+A6<&Z::baz> *a17_3; // expected-error{{non-type template argument of type 'double (Z::*)(double)' cannot be converted to a value of type 'int (Z::*)(int)'}}
template<int Z::*pm> struct A7; // expected-note{{template parameter is declared here}}
template<int Z::*pm> struct A7c;
A7<&Z::int_member> *a18_1;
A7c<&Z::int_member> *a18_2;
-A7<&Z::float_member> *a18_3; // expected-error{{non-type template argument of type 'float struct Z::*' cannot be converted to a value of type 'int struct Z::*'}}
+A7<&Z::float_member> *a18_3; // expected-error{{non-type template argument of type 'float Z::*' cannot be converted to a value of type 'int Z::*'}}
A7c<(&Z::int_member)> *a18_3; // expected-error{{non-type template argument cannot be surrounded by parentheses}}
template<unsigned char C> struct Overflow; // expected-note{{template parameter is declared here}}
diff --git a/test/SemaTemplate/temp_arg_type.cpp b/test/SemaTemplate/temp_arg_type.cpp
index a376900..a1db3f8 100644
--- a/test/SemaTemplate/temp_arg_type.cpp
+++ b/test/SemaTemplate/temp_arg_type.cpp
@@ -14,7 +14,7 @@ A<A<int> > *a6;
// [temp.arg.type]p2
void f() {
class X { };
- A<X> * a = 0; // expected-error{{template argument uses local type 'class X'}}
+ A<X> * a = 0; // expected-error{{template argument uses local type 'X'}}
}
struct { int x; } Unnamed; // expected-note{{unnamed type used in template argument was declared here}}
diff --git a/test/SemaTemplate/typename-specifier-4.cpp b/test/SemaTemplate/typename-specifier-4.cpp
index 0a6fef7..280a1b4 100644
--- a/test/SemaTemplate/typename-specifier-4.cpp
+++ b/test/SemaTemplate/typename-specifier-4.cpp
@@ -99,3 +99,20 @@ namespace PR6268 {
return Inner<U>();
}
}
+
+namespace PR6463 {
+ struct B { typedef int type; }; // expected-note 2{{member found by ambiguous name lookup}}
+ struct C { typedef int type; }; // expected-note 2{{member found by ambiguous name lookup}}
+
+ template<typename T>
+ struct A : B, C {
+ type& a(); // expected-error{{found in multiple base classes}}
+ int x;
+ };
+
+ // FIXME: Improve source location info here.
+ template<typename T>
+ typename A<T>::type& A<T>::a() { // expected-error{{found in multiple base classes}}
+ return x; // expected-error{{undeclared identifier}}
+ }
+}
diff --git a/test/SemaTemplate/typename-specifier.cpp b/test/SemaTemplate/typename-specifier.cpp
index b968ea6..42766a0 100644
--- a/test/SemaTemplate/typename-specifier.cpp
+++ b/test/SemaTemplate/typename-specifier.cpp
@@ -16,7 +16,7 @@ namespace N {
int i;
typename N::A::type *ip1 = &i;
-typename N::B::type *ip2 = &i; // expected-error{{no type named 'type' in 'struct N::B'}}
+typename N::B::type *ip2 = &i; // expected-error{{no type named 'type' in 'N::B'}}
typename N::C::type *ip3 = &i; // expected-error{{typename specifier refers to non-type member 'type'}}
void test(double d) {
@@ -33,8 +33,8 @@ void test(double d) {
namespace N {
template<typename T>
struct X {
- typedef typename T::type type; // expected-error {{no type named 'type' in 'struct N::B'}} \
- // expected-error {{no type named 'type' in 'struct B'}} \
+ typedef typename T::type type; // expected-error {{no type named 'type' in 'N::B'}} \
+ // expected-error {{no type named 'type' in 'B'}} \
// FIXME: location info for error above isn't very good \
// expected-error 2{{typename specifier refers to non-type member 'type'}} \
// expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
@@ -42,18 +42,18 @@ namespace N {
}
N::X<N::A>::type *ip4 = &i;
-N::X<N::B>::type *ip5 = &i; // expected-note{{in instantiation of template class 'struct N::X<struct N::B>' requested here}} \
+N::X<N::B>::type *ip5 = &i; // expected-note{{in instantiation of template class 'N::X<N::B>' requested here}} \
// expected-error{{no type named 'type' in}}
-N::X<N::C>::type *ip6 = &i; // expected-note{{in instantiation of template class 'struct N::X<struct N::C>' requested here}} \
+N::X<N::C>::type *ip6 = &i; // expected-note{{in instantiation of template class 'N::X<N::C>' requested here}} \
// expected-error{{no type named 'type' in}}
-N::X<int>::type fail1; // expected-note{{in instantiation of template class 'struct N::X<int>' requested here}} \
+N::X<int>::type fail1; // expected-note{{in instantiation of template class 'N::X<int>' requested here}} \
// expected-error{{no type named 'type' in}}
template<typename T>
struct Y {
- typedef typename N::X<T>::type *type; // expected-note{{in instantiation of template class 'struct N::X<struct B>' requested here}} \
- // expected-note{{in instantiation of template class 'struct N::X<struct C>' requested here}}
+ typedef typename N::X<T>::type *type; // expected-note{{in instantiation of template class 'N::X<B>' requested here}} \
+ // expected-note{{in instantiation of template class 'N::X<C>' requested here}}
};
struct A {
@@ -69,7 +69,7 @@ struct C {
};
::Y<A>::type ip7 = &i;
-::Y<B>::type ip8 = &i; // expected-note{{in instantiation of template class 'struct Y<struct B>' requested here}} \
+::Y<B>::type ip8 = &i; // expected-note{{in instantiation of template class 'Y<B>' requested here}} \
// expected-error{{no type named 'type' in}}
-::Y<C>::type ip9 = &i; // expected-note{{in instantiation of template class 'struct Y<struct C>' requested here}} \
+::Y<C>::type ip9 = &i; // expected-note{{in instantiation of template class 'Y<C>' requested here}} \
// expected-error{{no type named 'type' in}}
diff --git a/test/SemaTemplate/virtual-member-functions.cpp b/test/SemaTemplate/virtual-member-functions.cpp
index 58ac08c..8df808d 100644
--- a/test/SemaTemplate/virtual-member-functions.cpp
+++ b/test/SemaTemplate/virtual-member-functions.cpp
@@ -14,7 +14,7 @@ template<class T> int A<T>::a(T x) {
}
void f(A<int> x) {
- x.anchor(); // expected-note{{in instantiation of member function 'PR5557::A<int>::anchor' requested here}}
+ x.anchor();
}
template<typename T>
@@ -52,4 +52,4 @@ T *HasOutOfLineKey<T>::f(float *fp) {
return fp; // expected-error{{cannot initialize return object of type 'int *' with an lvalue of type 'float *'}}
}
-HasOutOfLineKey<int> out_of_line; // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::HasOutOfLineKey' requested here}}
+HasOutOfLineKey<int> out_of_line;
diff --git a/test/lit.cfg b/test/lit.cfg
index 3565edc..beb8ae0 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -97,18 +97,6 @@ if config.test_exec_root is None:
###
-import re
-site_exp = {}
-for line in open(os.path.join(config.llvm_obj_root, 'test', 'site.exp')):
- m = re.match('set ([^ ]+) "([^"]*)"', line)
- if m:
- site_exp[m.group(1)] = m.group(2)
-
-targets = set(site_exp['TARGETS_TO_BUILD'].split())
-def llvm_supports_target(name):
- return name in targets
-config.conditions['TARGET'] = llvm_supports_target
-
# Discover the 'clang' and 'clangcc' to use.
import os
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
index 07bb7fb..b52a32e 100644
--- a/tools/CIndex/CIndex.cpp
+++ b/tools/CIndex/CIndex.cpp
@@ -315,6 +315,7 @@ public:
bool VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
bool VisitExplicitCastExpr(ExplicitCastExpr *E);
bool VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
+ bool VisitObjCMessageExpr(ObjCMessageExpr *E);
};
} // end anonymous namespace
@@ -532,9 +533,10 @@ bool CursorVisitor::VisitVarDecl(VarDecl *D) {
}
bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
- // FIXME: We really need a TypeLoc covering Objective-C method declarations.
- // At the moment, we don't have information about locations in the return
- // type.
+ if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
+ if (Visit(TSInfo->getTypeLoc()))
+ return true;
+
for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
PEnd = ND->param_end();
P != PEnd; ++P) {
@@ -900,6 +902,14 @@ bool CursorVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
return VisitExpr(E);
}
+bool CursorVisitor::VisitObjCMessageExpr(ObjCMessageExpr *E) {
+ ObjCMessageExpr::ClassInfo CI = E->getClassInfo();
+ if (CI.Decl && Visit(MakeCursorObjCClassRef(CI.Decl, CI.Loc, TU)))
+ return true;
+
+ return VisitExpr(E);
+}
+
bool CursorVisitor::VisitAttributes(Decl *D) {
for (const Attr *A = D->getAttrs(); A; A = A->getNext())
if (Visit(MakeCXCursor(A, D, TU)))
@@ -1579,6 +1589,18 @@ unsigned clang_isTranslationUnit(enum CXCursorKind K) {
return K == CXCursor_TranslationUnit;
}
+unsigned clang_isUnexposed(enum CXCursorKind K) {
+ switch (K) {
+ case CXCursor_UnexposedDecl:
+ case CXCursor_UnexposedExpr:
+ case CXCursor_UnexposedStmt:
+ case CXCursor_UnexposedAttr:
+ return true;
+ default:
+ return false;
+ }
+}
+
CXCursorKind clang_getCursorKind(CXCursor C) {
return C.kind;
}
diff --git a/tools/CIndex/CIndex.exports b/tools/CIndex/CIndex.exports
index e68060b..5b95300 100644
--- a/tools/CIndex/CIndex.exports
+++ b/tools/CIndex/CIndex.exports
@@ -67,6 +67,7 @@ _clang_isInvalid
_clang_isReference
_clang_isStatement
_clang_isTranslationUnit
+_clang_isUnexposed
_clang_setUseExternalASTGeneration
_clang_tokenize
_clang_visitChildren
diff --git a/tools/Makefile b/tools/Makefile
index ce3e4cd..5a9c674 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -10,4 +10,11 @@
LEVEL := ../../..
DIRS := driver CIndex c-index-test
+include $(LEVEL)/Makefile.config
+
+ifeq ($(OS), $(filter $(OS), Cygwin MingW))
+DIRS := $(filter $(DIRS), CIndex)
+DIRS := $(filter $(DIRS), c-index-test)
+endif
+
include $(LEVEL)/Makefile.common
diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp
index fa0f0c2..46f4124 100644
--- a/tools/driver/driver.cpp
+++ b/tools/driver/driver.cpp
@@ -194,9 +194,9 @@ int main(int argc, const char **argv) {
Diagnostic Diags(&DiagClient);
#ifdef CLANG_IS_PRODUCTION
- bool IsProduction = true;
+ const bool IsProduction = true;
#else
- bool IsProduction = false;
+ const bool IsProduction = false;
#endif
Driver TheDriver(Path.getBasename(), Path.getDirname(),
llvm::sys::getHostTriple(),
diff --git a/tools/scan-build/ccc-analyzer b/tools/scan-build/ccc-analyzer
index e3db5ea..daf5f7f 100755
--- a/tools/scan-build/ccc-analyzer
+++ b/tools/scan-build/ccc-analyzer
@@ -380,13 +380,20 @@ my %UniqueOptions = (
'-isysroot' => 0
);
+##----------------------------------------------------------------------------##
+# Languages accepted.
+##----------------------------------------------------------------------------##
+
my %LangsAccepted = (
"objective-c" => 1,
- "c" => 1,
- "c++" => 1,
- "objective-c++" => 1
+ "c" => 1
);
+if (defined $ENV{'CCC_ANALYZER_CPLUSPLUS'}) {
+ $LangsAccepted{"c++"} = 1;
+ $LangsAccepted{"objective-c++"} = 1;
+}
+
##----------------------------------------------------------------------------##
# Main Logic.
##----------------------------------------------------------------------------##
OpenPOWER on IntegriCloud