summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-03-03 17:28:16 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-03-03 17:28:16 +0000
commitdf90325d4c0a65ee64d2dae3ed9b5b34f7418533 (patch)
treee1a885aadfd80632f5bd70d4bd2d37e715e35a79 /test
parentfd035e6496665b1f1197868e21cb0a4594e8db6e (diff)
downloadFreeBSD-src-df90325d4c0a65ee64d2dae3ed9b5b34f7418533.zip
FreeBSD-src-df90325d4c0a65ee64d2dae3ed9b5b34f7418533.tar.gz
Update clang to 97654.
Diffstat (limited to 'test')
-rw-r--r--test/ASTMerge/Inputs/category1.m25
-rw-r--r--test/ASTMerge/Inputs/category2.m27
-rw-r--r--test/ASTMerge/Inputs/exprs1.c10
-rw-r--r--test/ASTMerge/Inputs/exprs2.c10
-rw-r--r--test/ASTMerge/Inputs/interface1.m78
-rw-r--r--test/ASTMerge/Inputs/interface2.m77
-rw-r--r--test/ASTMerge/Inputs/namespace1.cpp17
-rw-r--r--test/ASTMerge/Inputs/namespace2.cpp17
-rw-r--r--test/ASTMerge/Inputs/property1.m12
-rw-r--r--test/ASTMerge/Inputs/property2.m13
-rw-r--r--test/ASTMerge/category.m9
-rw-r--r--test/ASTMerge/exprs.c4
-rw-r--r--test/ASTMerge/interface.m17
-rw-r--r--test/ASTMerge/namespace.cpp6
-rw-r--r--test/ASTMerge/property.m9
-rw-r--r--test/Analysis/blocks.m5
-rw-r--r--test/Analysis/dead-stores.m7
-rw-r--r--test/Analysis/inline.c20
-rw-r--r--test/Analysis/inline2.c14
-rw-r--r--test/Analysis/misc-ps-region-store.m21
-rw-r--r--test/Analysis/retain-release.m22
-rw-r--r--test/Analysis/unix-fns.c19
-rw-r--r--test/Analysis/unused-ivars.m15
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.classref/p3.cpp30
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp23
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp24
-rw-r--r--test/CXX/class.access/class.friend/p1.cpp62
-rw-r--r--test/CXX/class.derived/class.member.lookup/p6.cpp40
-rw-r--r--test/CXX/class/class.nest/p3.cpp25
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp43
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp12
-rw-r--r--test/CXX/expr/expr.unary/expr.new/p19.cpp46
-rw-r--r--test/CXX/expr/expr.unary/expr.new/p20-0x.cpp13
-rw-r--r--test/CXX/expr/expr.unary/expr.new/p20.cpp141
-rw-r--r--test/CXX/special/class.copy/p3.cpp27
-rw-r--r--test/CXX/temp/temp.decls/temp.mem/p1.cpp19
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp3
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp5
-rw-r--r--test/CXX/temp/temp.spec/temp.expl.spec/p6.cpp7
-rw-r--r--test/CXX/temp/temp.spec/temp.explicit/p4.cpp16
-rw-r--r--test/CXX/temp/temp.spec/temp.explicit/p6.cpp21
-rw-r--r--test/CodeGen/2010-02-16-DbgScopes.c18
-rw-r--r--test/CodeGen/2010-02-18-Dbg-VectorType.c9
-rw-r--r--test/CodeGen/attributes.c6
-rw-r--r--test/CodeGen/blocksignature.c94
-rw-r--r--test/CodeGen/builtins.c45
-rw-r--r--test/CodeGen/cast-emit.c12
-rw-r--r--test/CodeGen/dllimport-dllexport.c11
-rw-r--r--test/CodeGen/extern-inline.c25
-rw-r--r--test/CodeGen/functions.c21
-rw-r--r--test/CodeGenCXX/alloca-align.cpp26
-rw-r--r--test/CodeGenCXX/constructors.cpp94
-rw-r--r--test/CodeGenCXX/default-arguments.cpp6
-rw-r--r--test/CodeGenCXX/destructors.cpp107
-rw-r--r--test/CodeGenCXX/mangle-subst-std.cpp6
-rw-r--r--test/CodeGenCXX/mangle-template.cpp40
-rw-r--r--test/CodeGenCXX/mangle.cpp42
-rw-r--r--test/CodeGenCXX/virtual-base-destructor-call.cpp34
-rw-r--r--test/CodeGenCXX/virtual-bases.cpp4
-rw-r--r--test/CodeGenCXX/virtual-destructor-calls.cpp40
-rw-r--r--test/CodeGenCXX/vtable-layout-abi-examples.cpp189
-rw-r--r--test/CodeGenCXX/vtable-layout-extreme.cpp210
-rw-r--r--test/CodeGenCXX/vtable-layout.cpp671
-rw-r--r--test/CodeGenCXX/vtable-pointer-initialization.cpp15
-rw-r--r--test/CodeGenObjC/messages-2.m3
-rw-r--r--test/CodeGenObjC/stand-alone-implementation.m16
-rw-r--r--test/Driver/clang-c-as-cxx.c6
-rw-r--r--test/Index/Inputs/cindex-from-source.h1
-rw-r--r--test/Index/annotate-tokens.c3
-rw-r--r--test/Index/c-index-api-loadTU-test.m143
-rw-r--r--test/Index/cindex-from-source.m4
-rw-r--r--test/Index/cindex-on-invalid.m1
-rw-r--r--test/Index/code-complete-errors.c2
-rw-r--r--test/Index/linkage.c23
-rw-r--r--test/Lexer/constants.c16
-rw-r--r--test/PCH/Inputs/namespaces.h13
-rw-r--r--test/PCH/namespaces.cpp14
-rw-r--r--test/Parser/MicrosoftExtensions.c2
-rw-r--r--test/Parser/cxx-decl.cpp4
-rw-r--r--test/Parser/cxx-template-argument.cpp2
-rw-r--r--test/Parser/knr_parameter_attributes.c11
-rw-r--r--test/Preprocessor/directive-invalid.c7
-rw-r--r--test/Rewriter/dllimport-typedef.c17
-rw-r--r--test/Rewriter/missing-dllimport.c19
-rw-r--r--test/Rewriter/rewrite-block-pointer.mm48
-rw-r--r--test/Rewriter/rewrite-byref-in-nested-blocks.mm26
-rw-r--r--test/Rewriter/rewrite-implementation.mm2
-rw-r--r--test/Rewriter/rewrite-nested-blocks-1.mm47
-rw-r--r--test/Rewriter/rewrite-nested-blocks.mm56
-rw-r--r--test/Rewriter/rewrite-property-attributes.mm22
-rw-r--r--test/Rewriter/rewrite-qualified-id.mm21
-rw-r--r--test/Rewriter/rewrite-rewritten-initializer.mm28
-rw-r--r--test/Rewriter/rewrite-unique-block-api.mm8
-rw-r--r--test/Sema/align-x86.c6
-rw-r--r--test/Sema/arg-duplicate.c3
-rw-r--r--test/Sema/block-args.c3
-rw-r--r--test/Sema/callingconv.c8
-rw-r--r--test/Sema/conversion.c8
-rw-r--r--test/Sema/declspec.c5
-rw-r--r--test/Sema/dllimport-dllexport.c20
-rw-r--r--test/Sema/enum.c3
-rw-r--r--test/Sema/format-strings.c38
-rw-r--r--test/Sema/inline.c18
-rw-r--r--test/Sema/overloadable-complex.c12
-rw-r--r--test/Sema/static-init.c4
-rw-r--r--test/Sema/switch.c38
-rw-r--r--test/Sema/warn-unreachable.c4
-rw-r--r--test/Sema/warn-unused-function.c16
-rw-r--r--test/Sema/warn-unused-variables.c15
-rw-r--r--test/Sema/x86-attr-force-align-arg-pointer.c5
-rw-r--r--test/SemaCXX/address-of-temporary.cpp12
-rw-r--r--test/SemaCXX/attr-weakref.cpp31
-rw-r--r--test/SemaCXX/blocks-1.cpp35
-rw-r--r--test/SemaCXX/complex-overload.cpp12
-rw-r--r--test/SemaCXX/composite-pointer-type.cpp8
-rw-r--r--test/SemaCXX/condition.cpp3
-rw-r--r--test/SemaCXX/copy-constructor-error.cpp13
-rw-r--r--test/SemaCXX/dcl_init_aggr.cpp2
-rw-r--r--test/SemaCXX/default2.cpp3
-rw-r--r--test/SemaCXX/destructor.cpp21
-rw-r--r--test/SemaCXX/i-c-e-cxx.cpp5
-rw-r--r--test/SemaCXX/implicit-virtual-member-functions.cpp4
-rw-r--r--test/SemaCXX/invalid-member-expr.cpp4
-rw-r--r--test/SemaCXX/local-classes.cpp32
-rw-r--r--test/SemaCXX/member-name-lookup.cpp8
-rw-r--r--test/SemaCXX/member-pointer.cpp3
-rw-r--r--test/SemaCXX/nested-name-spec.cpp5
-rw-r--r--test/SemaCXX/new-delete.cpp6
-rw-r--r--test/SemaCXX/overload-call.cpp33
-rw-r--r--test/SemaCXX/pseudo-destructors.cpp18
-rw-r--r--test/SemaCXX/statements.cpp14
-rw-r--r--test/SemaCXX/type-convert-construct.cpp4
-rw-r--r--test/SemaCXX/warn-unreachable.cpp4
-rw-r--r--test/SemaObjC/category-1.m4
-rw-r--r--test/SemaObjC/conditional-expr-7.m30
-rw-r--r--test/SemaObjC/duplicate-ivar-in-class-extension.m32
-rw-r--r--test/SemaObjC/format-strings-objc.m5
-rw-r--r--test/SemaObjC/ivar-in-class-extension.m42
-rw-r--r--test/SemaObjC/ivar-in-implementations.m22
-rw-r--r--test/SemaObjC/method-warn-unused-attribute.m8
-rw-r--r--test/SemaObjC/property-and-class-extension.m36
-rw-r--r--test/SemaObjC/property-user-setter.m4
-rw-r--r--test/SemaObjC/stand-alone-implementation.m12
-rw-r--r--test/SemaObjC/unused.m21
-rw-r--r--test/SemaObjCXX/message.mm29
-rw-r--r--test/SemaObjCXX/vla.mm12
-rw-r--r--test/SemaTemplate/dependent-base-classes.cpp25
-rw-r--r--test/SemaTemplate/destructor-template.cpp15
-rw-r--r--test/SemaTemplate/explicit-specialization-member.cpp12
-rw-r--r--test/SemaTemplate/instantiate-complete.cpp17
-rw-r--r--test/SemaTemplate/instantiate-enum.cpp16
-rw-r--r--test/SemaTemplate/instantiate-expr-1.cpp33
-rw-r--r--test/SemaTemplate/instantiate-function-1.cpp6
-rw-r--r--test/SemaTemplate/instantiate-init.cpp11
-rw-r--r--test/SemaTemplate/instantiate-invalid.cpp52
-rw-r--r--test/SemaTemplate/instantiate-static-var.cpp23
-rw-r--r--test/SemaTemplate/member-access-expr.cpp2
-rw-r--r--test/SemaTemplate/nested-name-spec-template.cpp1
-rw-r--r--test/SemaTemplate/temp_arg.cpp7
-rw-r--r--test/SemaTemplate/template-decl-fail.cpp5
-rw-r--r--test/SemaTemplate/virtual-member-functions.cpp8
-rw-r--r--test/lit.cfg3
162 files changed, 4047 insertions, 233 deletions
diff --git a/test/ASTMerge/Inputs/category1.m b/test/ASTMerge/Inputs/category1.m
new file mode 100644
index 0000000..ade1c6c
--- /dev/null
+++ b/test/ASTMerge/Inputs/category1.m
@@ -0,0 +1,25 @@
+@interface I1
+@end
+
+// Matching category
+@interface I1 (Cat1)
+- (int)method0;
+@end
+
+// Matching class extension
+@interface I1 ()
+- (int)method1;
+@end
+
+// Mismatched category
+@interface I1 (Cat2)
+- (int)method2;
+@end
+
+@interface I2
+@end
+
+// Mismatched class extension
+@interface I2 ()
+- (int)method3;
+@end
diff --git a/test/ASTMerge/Inputs/category2.m b/test/ASTMerge/Inputs/category2.m
new file mode 100644
index 0000000..f66c208
--- /dev/null
+++ b/test/ASTMerge/Inputs/category2.m
@@ -0,0 +1,27 @@
+typedef int Int;
+
+@interface I1
+@end
+
+// Matching category
+@interface I1 (Cat1)
+- (Int)method0;
+@end
+
+// Matching class extension
+@interface I1 ()
+- (Int)method1;
+@end
+
+// Mismatched category
+@interface I1 (Cat2)
+- (float)method2;
+@end
+
+@interface I2
+@end
+
+// Mismatched class extension
+@interface I2 ()
+- (float)method3;
+@end
diff --git a/test/ASTMerge/Inputs/exprs1.c b/test/ASTMerge/Inputs/exprs1.c
new file mode 100644
index 0000000..1c268da
--- /dev/null
+++ b/test/ASTMerge/Inputs/exprs1.c
@@ -0,0 +1,10 @@
+// Matching
+enum E0 {
+ E0_Val0 = 'a',
+ E0_Val1 = (17),
+ E0_Val2 = (1 << 2),
+ E0_Val3 = E0_Val2,
+ E0_Val4 = sizeof(int*),
+ E0_Val5 = (unsigned int)-1
+};
+
diff --git a/test/ASTMerge/Inputs/exprs2.c b/test/ASTMerge/Inputs/exprs2.c
new file mode 100644
index 0000000..1c268da
--- /dev/null
+++ b/test/ASTMerge/Inputs/exprs2.c
@@ -0,0 +1,10 @@
+// Matching
+enum E0 {
+ E0_Val0 = 'a',
+ E0_Val1 = (17),
+ E0_Val2 = (1 << 2),
+ E0_Val3 = E0_Val2,
+ E0_Val4 = sizeof(int*),
+ E0_Val5 = (unsigned int)-1
+};
+
diff --git a/test/ASTMerge/Inputs/interface1.m b/test/ASTMerge/Inputs/interface1.m
index 1aa1c3b..7e9935d 100644
--- a/test/ASTMerge/Inputs/interface1.m
+++ b/test/ASTMerge/Inputs/interface1.m
@@ -1,7 +1,81 @@
// Matches
-@interface I1
+@interface I1 {
+ int ivar1;
+}
@end
// Matches
-@interface I2 : I1
+@interface I2 : I1 {
+ float ivar2;
+}
+@end
+
+// Ivar mismatch
+@interface I3 {
+ int ivar1;
+ int ivar2;
+}
+@end
+
+// Superclass mismatch
+@interface I4 : I2 {
+}
+@end
+
+// Methods match
+@interface I5
+- (int)foo;
++ (float)bar;
+@end
+
+// Method mismatch
+@interface I6
+- (int)foo;
++ (int)foo;
+@end
+
+// Method mismatch
+@interface I7
+- (int)foo;
++ (int)bar:(int)x;
+@end
+
+// Method mismatch
+@interface I8
+- (int)foo;
++ (int)bar:(float)x;
+@end
+
+// Matching protocol
+@protocol P0
++ (int)foo;
+- (int)bar:(float)x;
+@end
+
+// Protocol with mismatching method
+@protocol P1
++ (int)foo;
+- (int)bar:(float)x;
+@end
+
+// Interface with protocol
+@interface I9 <P0>
++ (int)foo;
+- (int)bar:(float)x;
+@end
+
+// Protocol with protocol
+@protocol P2 <P0>
+- (float)wibble:(int)a1 second:(int)a2;
+@end
+
+// Forward-declared interfaces
+@class I10, I11;
+@interface I12
+@end
+
+// Forward-declared protocols
+@protocol P3, P5;
+@protocol P4
+- (double)honk:(int)a;
@end
diff --git a/test/ASTMerge/Inputs/interface2.m b/test/ASTMerge/Inputs/interface2.m
index 1aa1c3b..bef7fb8 100644
--- a/test/ASTMerge/Inputs/interface2.m
+++ b/test/ASTMerge/Inputs/interface2.m
@@ -1,7 +1,80 @@
// Matches
-@interface I1
+@interface I1 {
+ int ivar1;
+}
@end
// Matches
-@interface I2 : I1
+@interface I2 : I1 {
+ float ivar2;
+}
+@end
+
+// Ivar mismatch
+@interface I3 {
+ int ivar1;
+ float ivar2;
+}
+@end
+
+// Superclass mismatch
+@interface I4 : I1 {
+}
+@end
+
+// Methods match
+@interface I5
++ (float)bar;
+- (int)foo;
+@end
+
+// Method mismatch
+@interface I6
++ (float)foo;
+@end
+
+// Method mismatch
+@interface I7
+- (int)foo;
++ (int)bar:(float)x;
+@end
+
+// Method mismatch
+@interface I8
+- (int)foo;
++ (int)bar:(float)x, ...;
+@end
+
+// Matching protocol
+@protocol P0
++ (int)foo;
+- (int)bar:(float)x;
+@end
+
+// Protocol with mismatching method
+@protocol P1
++ (int)foo;
+- (int)bar:(double)x;
+@end
+
+// Interface with protocol
+@interface I9 <P0>
++ (int)foo;
+- (int)bar:(float)x;
+@end
+
+// Protocol with protocol
+@protocol P2 <P0>
+- (float)wibble:(int)a1 second:(int)a2;
+@end
+
+// Forward-declared interface
+@class I12, I10;
+@interface I11
+@end
+
+// Forward-declared protocols
+@protocol P3, P4;
+@protocol P5
+- (double)honk:(int)a;
@end
diff --git a/test/ASTMerge/Inputs/namespace1.cpp b/test/ASTMerge/Inputs/namespace1.cpp
new file mode 100644
index 0000000..1ff84f31
--- /dev/null
+++ b/test/ASTMerge/Inputs/namespace1.cpp
@@ -0,0 +1,17 @@
+// Merge success
+namespace N1 {
+ int x;
+}
+
+// Merge multiple namespaces
+namespace N2 {
+ extern int x;
+}
+namespace N2 {
+ extern float y;
+}
+
+// Merge namespace with conflict
+namespace N3 {
+ extern float z;
+}
diff --git a/test/ASTMerge/Inputs/namespace2.cpp b/test/ASTMerge/Inputs/namespace2.cpp
new file mode 100644
index 0000000..80429f7
--- /dev/null
+++ b/test/ASTMerge/Inputs/namespace2.cpp
@@ -0,0 +1,17 @@
+// Merge success
+namespace N1 {
+ extern int x0;
+}
+
+// Merge multiple namespaces
+namespace N2 {
+ extern int x;
+}
+namespace N2 {
+ extern float y;
+}
+
+// Merge namespace with conflict
+namespace N3 {
+ extern double z;
+}
diff --git a/test/ASTMerge/Inputs/property1.m b/test/ASTMerge/Inputs/property1.m
new file mode 100644
index 0000000..37887a3
--- /dev/null
+++ b/test/ASTMerge/Inputs/property1.m
@@ -0,0 +1,12 @@
+// Matching properties
+@interface I1 {
+}
+- (int)getProp2;
+- (void)setProp2:(int)value;
+@end
+
+// Mismatched property
+@interface I2
+@property (readonly) float Prop1;
+@end
+
diff --git a/test/ASTMerge/Inputs/property2.m b/test/ASTMerge/Inputs/property2.m
new file mode 100644
index 0000000..6039f10
--- /dev/null
+++ b/test/ASTMerge/Inputs/property2.m
@@ -0,0 +1,13 @@
+// Matching properties
+@interface I1 {
+}
+- (int)getProp2;
+- (void)setProp2:(int)value;
+@property (readonly) int Prop1;
+@property (getter = getProp2, setter = setProp2:) int Prop2;
+@end
+
+// Mismatched property
+@interface I2
+@property (readonly) int Prop1;
+@end
diff --git a/test/ASTMerge/category.m b/test/ASTMerge/category.m
new file mode 100644
index 0000000..bf0d11b
--- /dev/null
+++ b/test/ASTMerge/category.m
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/category1.m
+// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/category2.m
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+
+// CHECK: category2.m:18:1: error: instance method 'method2' has incompatible result types in different translation units ('float' vs. 'int')
+// CHECK: category1.m:16:1: note: instance method 'method2' also declared here
+// CHECK: category2.m:26:1: error: instance method 'method3' has incompatible result types in different translation units ('float' vs. 'int')
+// CHECK: category1.m:24:1: note: instance method 'method3' also declared here
+// CHECK: 4 diagnostics generated.
diff --git a/test/ASTMerge/exprs.c b/test/ASTMerge/exprs.c
new file mode 100644
index 0000000..0a4e1e5
--- /dev/null
+++ b/test/ASTMerge/exprs.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/exprs1.c
+// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/exprs2.c
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only -verify %s
+
diff --git a/test/ASTMerge/interface.m b/test/ASTMerge/interface.m
index d6af2f4..47e4e05 100644
--- a/test/ASTMerge/interface.m
+++ b/test/ASTMerge/interface.m
@@ -1,6 +1,19 @@
// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/interface1.m
// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/interface2.m
-// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
-// FIXME: FileCheck!
+// CHECK: interface2.m:16:9: error: instance variable 'ivar2' declared with incompatible types in different translation units ('float' vs. 'int')
+// CHECK: interface1.m:16:7: note: declared here with type 'int'
+// CHECK: interface1.m:21:1: error: class 'I4' has incompatible superclasses
+// CHECK: interface1.m:21:17: note: inherits from superclass 'I2' here
+// CHECK: interface2.m:21:17: note: inherits from superclass 'I1' here
+// CHECK: interface2.m:33:1: error: class method 'foo' has incompatible result types in different translation units ('float' vs. 'int')
+// CHECK: interface1.m:34:1: note: class method 'foo' also declared here
+// CHECK: interface2.m:39:19: error: class method 'bar:' has a parameter with a different types in different translation units ('float' vs. 'int')
+// CHECK: interface1.m:40:17: note: declared here with type 'int'
+// CHECK: interface2.m:45:1: error: class method 'bar:' is variadic in one translation unit and not variadic in another
+// CHECK: interface1.m:46:1: note: class method 'bar:' also declared here
+// CHECK: interface2.m:57:20: error: instance method 'bar:' has a parameter with a different types in different translation units ('double' vs. 'float')
+// CHECK: interface1.m:58:19: note: declared here with type 'float'
+// CHECK: 13 diagnostics generated
diff --git a/test/ASTMerge/namespace.cpp b/test/ASTMerge/namespace.cpp
new file mode 100644
index 0000000..6c46f0a
--- /dev/null
+++ b/test/ASTMerge/namespace.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/namespace1.cpp
+// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/namespace2.cpp
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+
+// CHECK: namespace2.cpp:16:17: error: external variable 'z' declared with incompatible types in different translation units ('double' vs. 'float')
+// CHECK: namespace1.cpp:16:16: note: declared here with type 'float'
diff --git a/test/ASTMerge/property.m b/test/ASTMerge/property.m
new file mode 100644
index 0000000..0fd7e48
--- /dev/null
+++ b/test/ASTMerge/property.m
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/property1.m
+// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/property2.m
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+
+// CHECK: property2.m:12:26: error: property 'Prop1' declared with incompatible types in different translation units ('int' vs. 'float')
+// CHECK: property1.m:10:28: note: declared here with type 'float'
+// CHECK: property2.m:12:26: error: instance method 'Prop1' has incompatible result types in different translation units ('int' vs. 'float')
+// CHECK: property1.m:10:28: note: instance method 'Prop1' also declared here
+// CHECK: 4 diagnostics generated.
diff --git a/test/Analysis/blocks.m b/test/Analysis/blocks.m
index e8e96a2..b05b198 100644
--- a/test/Analysis/blocks.m
+++ b/test/Analysis/blocks.m
@@ -83,3 +83,8 @@ void test2_b() {
// 'x' is bound at block creation.
^{ y = x + 1; }(); // no-warning
}
+
+void test2_c() {
+ typedef void (^myblock)(void);
+ myblock f = ^() { f(); }; // expected-warning{{Variable 'f' is captured by block with a garbage value}}
+} \ No newline at end of file
diff --git a/test/Analysis/dead-stores.m b/test/Analysis/dead-stores.m
index 765a24a..701e580 100644
--- a/test/Analysis/dead-stores.m
+++ b/test/Analysis/dead-stores.m
@@ -34,3 +34,10 @@ void DeadStoreTest(NSObject *anObject) {
([keys containsObject:@"name"] && [keys containsObject:@"icon"])) {}
}
+// This test case was a false positive due to how clang models
+// pointer types and ObjC object pointer types differently. Here
+// we don't warn about a dead store because 'nil' is assigned to
+// an object pointer for the sake of defensive programming.
+void rdar_7631278(NSObject *x) {
+ x = ((void*)0);
+}
diff --git a/test/Analysis/inline.c b/test/Analysis/inline.c
new file mode 100644
index 0000000..13d4f7f
--- /dev/null
+++ b/test/Analysis/inline.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f2 -verify %s
+
+int f1() {
+ int y = 1;
+ y++;
+ return y;
+}
+
+void f2() {
+ int x = 1;
+ x = f1();
+ if (x == 1) {
+ int *p = 0;
+ *p = 3; // no-warning
+ }
+ if (x == 2) {
+ int *p = 0;
+ *p = 3; // expected-warning{{Dereference of null pointer loaded from variable}}
+ }
+}
diff --git a/test/Analysis/inline2.c b/test/Analysis/inline2.c
new file mode 100644
index 0000000..e2758c1
--- /dev/null
+++ b/test/Analysis/inline2.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f2 -verify %s
+
+// Test parameter 'a' is registered to LiveVariables analysis data although it
+// is not referenced in the function body.
+// Before processing 'return 1;', in RemoveDeadBindings(), we query the liveness
+// of 'a', because we have a binding for it due to parameter passing.
+int f1(int a) {
+ return 1;
+}
+
+void f2() {
+ int x;
+ x = f1(1);
+}
diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m
index 201cbc9..21a54c3 100644
--- a/test/Analysis/misc-ps-region-store.m
+++ b/test/Analysis/misc-ps-region-store.m
@@ -1,6 +1,10 @@
// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -DTEST_64 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
+typedef long unsigned int size_t;
+void *memcpy(void *, const void *, size_t);
+void *alloca(size_t);
+
typedef struct objc_selector *SEL;
typedef signed char BOOL;
typedef int NSInteger;
@@ -867,3 +871,20 @@ int test_c_rev96062() {
test_a_rev96062_aux2(&z);
return a + b; // no-warning
}
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7242010> - The access to y[0] at the bottom previously
+// was reported as an uninitialized value.
+//===----------------------------------------------------------------------===//
+
+char *rdar_7242010(int count, char **y) {
+ char **x = alloca((count + 4) * sizeof(*x));
+ x[0] = "hi";
+ x[1] = "there";
+ x[2] = "every";
+ x[3] = "body";
+ memcpy(x + 4, y, count * sizeof(*x));
+ y = x;
+ return y[0]; // no-warning
+}
+
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
index 1c41d85..675e9a6 100644
--- a/test/Analysis/retain-release.m
+++ b/test/Analysis/retain-release.m
@@ -7,6 +7,12 @@
#if __has_feature(attribute_cf_returns_retained)
#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
#endif
+#if __has_feature(attribute_ns_returns_not_retained)
+#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
+#endif
+#if __has_feature(attribute_cf_returns_not_retained)
+#define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
+#endif
//===----------------------------------------------------------------------===//
// The following code is reduced using delta-debugging from Mac OS X headers:
@@ -1188,6 +1194,8 @@ typedef NSString* MyStringTy;
- (NSString*) returnsAnOwnedString NS_RETURNS_RETAINED; // no-warning
- (NSString*) returnsAnOwnedCFString CF_RETURNS_RETAINED; // no-warning
- (MyStringTy) returnsAnOwnedTypedString NS_RETURNS_RETAINED; // no-warning
+- (NSString*) newString NS_RETURNS_NOT_RETAINED; // no-warning
+- (NSString*) newStringNoAttr;
- (int) returnsAnOwnedInt NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to functions or methods that return a pointer or Objective-C object}}
@end
@@ -1201,9 +1209,16 @@ void test_attr_1b(TestOwnershipAttr *X) {
NSString *str = [X returnsAnOwnedCFString]; // expected-warning{{leak}}
}
+void test_attr1c(TestOwnershipAttr *X) {
+ NSString *str = [X newString]; // no-warning
+ NSString *str2 = [X newStringNoAttr]; // expected-warning{{leak}}
+}
+
@interface MyClassTestCFAttr : NSObject {}
- (NSDate*) returnsCFRetained CF_RETURNS_RETAINED;
- (CFDateRef) returnsCFRetainedAsCF CF_RETURNS_RETAINED;
+- (CFDateRef) newCFRetainedAsCF CF_RETURNS_NOT_RETAINED;
+- (CFDateRef) newCFRetainedAsCFNoAttr;
- (NSDate*) alsoReturnsRetained;
- (CFDateRef) alsoReturnsRetainedAsCF;
- (NSDate*) returnsNSRetained NS_RETURNS_RETAINED;
@@ -1223,6 +1238,13 @@ CFDateRef returnsRetainedCFDate() {
return returnsRetainedCFDate(); // No leak.
}
+- (CFDateRef) newCFRetainedAsCF {
+ return (CFDateRef)[(id)[self returnsCFRetainedAsCF] autorelease];
+}
+
+- (CFDateRef) newCFRetainedAsCFNoAttr {
+ return (CFDateRef)[(id)[self returnsCFRetainedAsCF] autorelease]; // expected-warning{{Object with +0 retain counts returned to caller where a +1 (owning) retain count is expected}}
+}
- (NSDate*) alsoReturnsRetained {
return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}}
diff --git a/test/Analysis/unix-fns.c b/test/Analysis/unix-fns.c
new file mode 100644
index 0000000..777ad19
--- /dev/null
+++ b/test/Analysis/unix-fns.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem %s -analyzer-store=region
+// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem %s -analyzer-store=basic
+
+#ifndef O_CREAT
+#define O_CREAT 0x0200
+#define O_RDONLY 0x0000
+#endif
+int open(const char *, int, ...);
+
+void test_open(const char *path) {
+ int fd;
+ fd = open(path, O_RDONLY); // no-warning
+ if (!fd)
+ close(fd);
+
+ fd = open(path, O_CREAT); // expected-warning{{Call to 'open' requires a third argument when the 'O_CREAT' flag is set}}
+ if (!fd)
+ close(fd);
+}
diff --git a/test/Analysis/unused-ivars.m b/test/Analysis/unused-ivars.m
index 600f0e2..14c43a8 100644
--- a/test/Analysis/unused-ivars.m
+++ b/test/Analysis/unused-ivars.m
@@ -81,3 +81,18 @@ int radar_7254495(RDar7254495 *a) {
return a->x;
}
@end
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7353683> - consult attribute((unused)) to silence warnings
+// about unused instance variables
+//===----------------------------------------------------------------------===//
+
+@interface RDar7353683 {
+@private
+ id x __attribute__((unused));
+}
+@end
+
+@implementation RDar7353683
+@end
+
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.classref/p3.cpp b/test/CXX/basic/basic.lookup/basic.lookup.classref/p3.cpp
new file mode 100644
index 0000000..4a0b387
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.classref/p3.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++0x [basic.lookup.classref]p3:
+// If the unqualified-id is ∼type-name, the type-name is looked up in the
+// context of the entire postfix-expression. If the type T of the object
+// expression is of a class type C, the type-name is also looked up in the
+// scope of class C. At least one of the lookups shall find a name that
+// refers to (possibly cv-qualified) T.
+
+// From core issue 305
+struct A {
+};
+
+struct C {
+ struct A {};
+ void f ();
+};
+
+void C::f () {
+ ::A *a;
+ a->~A ();
+}
+
+// From core issue 414
+struct X {};
+void f() {
+ X x;
+ struct X {};
+ x.~X();
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp
new file mode 100644
index 0000000..35efba5
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6-0x.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+struct C {
+ typedef int I;
+};
+
+typedef int I1, I2;
+extern int* p;
+extern int* q;
+
+void f() {
+ p->C::I::~I();
+ q->I1::~I2();
+}
+
+struct A {
+ ~A();
+};
+
+typedef A AB;
+int main() {
+ AB *p;
+ p->AB::~AB();
+}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp
new file mode 100644
index 0000000..633d5cd
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.qual/p6.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct C {
+ typedef int I;
+};
+
+typedef int I1, I2;
+extern int* p;
+extern int* q;
+
+void f() {
+ p->C::I::~I();
+ q->I1::~I2();
+}
+
+struct A {
+ ~A();
+};
+
+typedef A AB;
+int main() {
+ AB *p;
+ p->AB::~AB(); // expected-error{{identifier 'AB' in pseudo-destructor expression does not name a type}}
+}
diff --git a/test/CXX/class.access/class.friend/p1.cpp b/test/CXX/class.access/class.friend/p1.cpp
new file mode 100644
index 0000000..22f77b0
--- /dev/null
+++ b/test/CXX/class.access/class.friend/p1.cpp
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++'0x [class.friend] p1:
+// A friend of a class is a function or class that is given permission to use
+// the private and protected member names from the class. A class specifies
+// its friends, if any, by way of friend declarations. Such declarations give
+// special access rights to the friends, but they do not make the nominated
+// friends members of the befriending class.
+//
+// FIXME: Add tests for access control when implemented. Currently we only test
+// for parsing.
+
+struct S { static void f(); };
+S* g() { return 0; }
+
+struct X {
+ friend struct S;
+ friend S* g();
+};
+
+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 x;
+ x.g(); // expected-error{{no member named 'g' in 'struct X'}}
+}
+
+// Test that we recurse through namespaces to find already declared names, but
+// new names are declared within the enclosing namespace.
+namespace N {
+ struct X {
+ friend struct S;
+ friend S* g();
+
+ friend struct S2;
+ friend struct S2* g2();
+ };
+
+ struct S2 { static void f2(); };
+ S2* g2() { return 0; }
+
+ void test() {
+ 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 x;
+ x.g(); // expected-error{{no member named 'g' in 'struct 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'}}
+ }
+}
diff --git a/test/CXX/class.derived/class.member.lookup/p6.cpp b/test/CXX/class.derived/class.member.lookup/p6.cpp
new file mode 100644
index 0000000..5f4b2a7
--- /dev/null
+++ b/test/CXX/class.derived/class.member.lookup/p6.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class V {
+public:
+ int f();
+ int x;
+};
+
+class W {
+public:
+ int g(); // expected-note{{member found by ambiguous name lookup}}
+ int y; // expected-note{{member found by ambiguous name lookup}}
+};
+
+class B : public virtual V, public W
+{
+public:
+ int f();
+ int x;
+ int g(); // expected-note{{member found by ambiguous name lookup}}
+ int y; // expected-note{{member found by ambiguous name lookup}}
+};
+
+class C : public virtual V, public W { };
+
+class D : public B, public C { void glorp(); };
+
+void D::glorp() {
+ x++;
+ f();
+ y++; // expected-error{{member 'y' found in multiple base classes of different types}}
+ g(); // expected-error{{error: member 'g' found in multiple base classes of different types}}
+}
+
+// PR6462
+struct BaseIO { BaseIO* rdbuf() { return 0; } };
+struct Pcommon : virtual BaseIO { int rdbuf() { return 0; } };
+struct P : virtual BaseIO, Pcommon {};
+
+void f() { P p; p.rdbuf(); }
diff --git a/test/CXX/class/class.nest/p3.cpp b/test/CXX/class/class.nest/p3.cpp
new file mode 100644
index 0000000..c4c4ca7
--- /dev/null
+++ b/test/CXX/class/class.nest/p3.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++0x [class.nest] p3:
+// If class X is defined in a namespace scope, a nested class Y may be
+// declared in class X and later defined in the definition of class X or be
+// later defined in a namespace scope enclosing the definition of class X.
+
+namespace example {
+ class E {
+ class I1;
+ class I2;
+ class I1 { };
+ };
+ class E::I2 { };
+}
+
+// Don't insert out-of-line inner class definitions into the namespace scope.
+namespace PR6107 {
+ struct S1 { };
+ struct S2 {
+ struct S1;
+ };
+ struct S2::S1 { };
+ S1 s1;
+}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp
index 1f962a9..a5f314d 100644
--- a/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp
@@ -1,5 +1,47 @@
// RUN: %clang_cc1 -fsyntax-only %s
+// C++'0x [namespace.memdef] p3:
+// Every name first declared in a namespace is a member of that namespace. If
+// a friend declaration in a non-local class first declares a class or
+// function the friend class or function is a member of the innermost
+// enclosing namespace.
+
+namespace N {
+ struct S0 {
+ friend struct F0;
+ friend void f0(int);
+ struct F0 member_func();
+ };
+ struct F0 { };
+ F0 f0() { return S0().member_func(); }
+}
+N::F0 f0_var = N::f0();
+
+// Ensure we can handle attaching friend declarations to an enclosing namespace
+// with multiple contexts.
+namespace N { struct S1 { struct IS1; }; }
+namespace N {
+ struct S1::IS1 {
+ friend struct F1;
+ friend void f1(int);
+ struct F1 member_func();
+ };
+ struct F1 { };
+ F1 f1() { return S1::IS1().member_func(); }
+}
+N::F1 f1_var = N::f1();
+
+// The name of the friend is not found by unqualified lookup (3.4.1) or by
+// qualified lookup (3.4.3) until a matching declaration is provided in that
+// namespace scope (either before or after the class definition granting
+// friendship). If a friend function is called, its name may be found by the
+// name lookup that considers functions from namespaces and classes
+// associated with the types of the function arguments (3.4.2). If the name
+// in a friend declaration is neither qualified nor a template-id and the
+// declaration is a function or an elaborated-type-specifier, the lookup to
+// determine whether the entity has been previously declared shall not
+// consider any scopes outside the innermost enclosing namespace.
+
template<typename T> struct X0 { };
struct X1 { };
@@ -11,5 +53,4 @@ struct Y {
friend union X1;
};
-
// FIXME: Woefully inadequate for testing
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp
index cf52909..4c7ee94 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5.cpp
@@ -10,3 +10,15 @@ namespace PR5909 {
const Foo f = { 0 }; // It compiles without the 'const'.
bool z = Test(f.x);
}
+
+namespace PR6264 {
+ typedef int (&T)[3];
+ struct S
+ {
+ operator T ();
+ };
+ void f()
+ {
+ T bar = S();
+ }
+}
diff --git a/test/CXX/expr/expr.unary/expr.new/p19.cpp b/test/CXX/expr/expr.unary/expr.new/p19.cpp
new file mode 100644
index 0000000..6134779
--- /dev/null
+++ b/test/CXX/expr/expr.unary/expr.new/p19.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+typedef __SIZE_TYPE__ size_t;
+
+// Operator delete template for placement new with global lookup
+template<int I>
+struct X0 {
+ X0();
+
+ static void* operator new(size_t) {
+ return I; // expected-error{{cannot initialize}}
+ }
+
+ static void operator delete(void*) {
+ int *ip = I; // expected-error{{cannot initialize}}
+ }
+};
+
+void test_X0() {
+ // Using the global operator new suppresses the search for a
+ // operator delete in the class.
+ ::new X0<2>;
+
+ new X0<3>; // expected-note 2{{instantiation}}
+}
+
+// Operator delete template for placement new[] with global lookup
+template<int I>
+struct X1 {
+ X1();
+
+ static void* operator new[](size_t) {
+ return I; // expected-error{{cannot initialize}}
+ }
+
+ static void operator delete[](void*) {
+ int *ip = I; // expected-error{{cannot initialize}}
+ }
+};
+
+void test_X1() {
+ // Using the global operator new suppresses the search for a
+ // operator delete in the class.
+ ::new X1<2> [17];
+
+ new X1<3> [17]; // expected-note 2{{instantiation}}
+}
diff --git a/test/CXX/expr/expr.unary/expr.new/p20-0x.cpp b/test/CXX/expr/expr.unary/expr.new/p20-0x.cpp
new file mode 100644
index 0000000..c188e1e
--- /dev/null
+++ b/test/CXX/expr/expr.unary/expr.new/p20-0x.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+typedef __SIZE_TYPE__ size_t;
+
+struct S {
+ // Placement allocation function:
+ static void* operator new(size_t, size_t);
+ // Usual (non-placement) deallocation function:
+ static void operator delete(void*, size_t); // expected-note{{declared here}}
+};
+
+void testS() {
+ S* p = new (0) S; // expected-error{{'new' expression with placement arguments refers to non-placement 'operator delete'}}
+}
diff --git a/test/CXX/expr/expr.unary/expr.new/p20.cpp b/test/CXX/expr/expr.unary/expr.new/p20.cpp
new file mode 100644
index 0000000..71e584e
--- /dev/null
+++ b/test/CXX/expr/expr.unary/expr.new/p20.cpp
@@ -0,0 +1,141 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+typedef __SIZE_TYPE__ size_t;
+
+// Overloaded operator delete with two arguments
+template<int I>
+struct X0 {
+ X0();
+ static void* operator new(size_t);
+ static void operator delete(void*, size_t) {
+ int *ip = I; // expected-error{{cannot initialize}}
+ }
+};
+
+void test_X0() {
+ new X0<1>; // expected-note{{instantiation}}
+}
+
+// Overloaded operator delete with one argument
+template<int I>
+struct X1 {
+ X1();
+
+ static void* operator new(size_t);
+ static void operator delete(void*) {
+ int *ip = I; // expected-error{{cannot initialize}}
+ }
+};
+
+void test_X1() {
+ new X1<1>; // expected-note{{instantiation}}
+}
+
+// Overloaded operator delete for placement new
+template<int I>
+struct X2 {
+ X2();
+
+ static void* operator new(size_t, double, double);
+ static void* operator new(size_t, int, int);
+
+ static void operator delete(void*, const int, int) {
+ int *ip = I; // expected-error{{cannot initialize}}
+ }
+
+ static void operator delete(void*, double, double);
+};
+
+void test_X2() {
+ new (0, 0) X2<1>; // expected-note{{instantiation}}
+}
+
+// Operator delete template for placement new
+struct X3 {
+ X3();
+
+ static void* operator new(size_t, double, double);
+
+ template<typename T>
+ static void operator delete(void*, T x, T) {
+ double *dp = &x;
+ int *ip = &x; // expected-error{{cannot initialize}}
+ }
+};
+
+void test_X3() {
+ new (0, 0) X3; // expected-note{{instantiation}}
+}
+
+// Operator delete template for placement new in global scope.
+struct X4 {
+ X4();
+ static void* operator new(size_t, double, double);
+};
+
+template<typename T>
+void operator delete(void*, T x, T) {
+ double *dp = &x;
+ int *ip = &x; // expected-error{{cannot initialize}}
+}
+
+void test_X4() {
+ new (0, 0) X4; // expected-note{{instantiation}}
+}
+
+// Useless operator delete hides global operator delete template.
+struct X5 {
+ X5();
+ static void* operator new(size_t, double, double);
+ void operator delete(void*, double*, double*);
+};
+
+void test_X5() {
+ new (0, 0) X5; // okay, we found X5::operator delete but didn't pick it
+}
+
+// Operator delete template for placement new
+template<int I>
+struct X6 {
+ X6();
+
+ static void* operator new(size_t) {
+ return I; // expected-error{{cannot initialize}}
+ }
+
+ static void operator delete(void*) {
+ int *ip = I; // expected-error{{cannot initialize}}
+ }
+};
+
+void test_X6() {
+ new X6<3>; // expected-note 2{{instantiation}}
+}
+
+void *operator new(size_t, double, double, double);
+
+template<typename T>
+void operator delete(void*, T x, T, T) {
+ double *dp = &x;
+ int *ip = &x; // expected-error{{cannot initialize}}
+}
+void test_int_new() {
+ new (1.0, 1.0, 1.0) int; // expected-note{{instantiation}}
+}
+
+// We don't need an operator delete if the type has a trivial
+// constructor, since we know that constructor cannot throw.
+// FIXME: Is this within the standard? Seems fishy, but both EDG+GCC do it.
+#if 0
+template<int I>
+struct X7 {
+ static void* operator new(size_t);
+ static void operator delete(void*, size_t) {
+ int *ip = I; // okay, since it isn't instantiated.
+ }
+};
+
+void test_X7() {
+ new X7<1>;
+}
+#endif
+
diff --git a/test/CXX/special/class.copy/p3.cpp b/test/CXX/special/class.copy/p3.cpp
new file mode 100644
index 0000000..3d87266
--- /dev/null
+++ b/test/CXX/special/class.copy/p3.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s
+
+// PR6141
+template<typename T>
+struct X {
+ X();
+ template<typename U> X(X<U>);
+ X(const X<T>&);
+};
+
+void f(X<int>) { }
+
+struct Y : X<int> { };
+struct Z : X<float> { };
+
+// CHECK: define i32 @main()
+int main() {
+ // CHECK: call void @_ZN1YC1Ev
+ // CHECK: call void @_ZN1XIiEC1ERKS0_
+ // CHECK: call void @_Z1f1XIiE
+ f(Y());
+ // CHECK: call void @_ZN1ZC1Ev
+ // CHECK: call void @_ZN1XIfEC1ERKS0_
+ // CHECK: call void @_ZN1XIiEC1IfEES_IT_E
+ // CHECK: call void @_Z1f1XIiE
+ f(Z());
+}
diff --git a/test/CXX/temp/temp.decls/temp.mem/p1.cpp b/test/CXX/temp/temp.decls/temp.mem/p1.cpp
index 1b9da84..b057eed 100644
--- a/test/CXX/temp/temp.decls/temp.mem/p1.cpp
+++ b/test/CXX/temp/temp.decls/temp.mem/p1.cpp
@@ -14,3 +14,22 @@ int foo() {
A<bool>::cond = true;
return A<bool>::B<int>::twice(4);
}
+
+namespace PR6376 {
+ template<typename T>
+ struct X {
+ template<typename Y>
+ struct Y { };
+ };
+
+ template<>
+ struct X<float> {
+ template<typename Y>
+ struct Y { };
+ };
+
+ template<typename T, typename U>
+ struct Z : public X<T>::template Y<U> { };
+
+ Z<float, int> z0;
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp
index a8b83d4..eb5465c 100644
--- a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp
@@ -33,5 +33,4 @@ template <typename T> void g(T);
template <typename T> void g(T, T);
int typeof2[is_same<__typeof__(g<float>), void (int)>::value? 1 : -1]; // \
- // expected-error{{cannot determine the type of an overloaded function}} \
- // FIXME: expected-error{{use of undeclared identifier}}
+ // expected-error{{cannot determine the type of an overloaded function}}
diff --git a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp
index 95f9640..dc79300 100644
--- a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp
@@ -3,8 +3,9 @@
template<class X, class Y, class Z> X f(Y,Z); // expected-note {{candidate template ignored: couldn't infer template argument 'X'}}
void g() {
- f<int,char*,double>("aa",3.0);
- f<int,char*>("aa",3.0); // Z is deduced to be double
+ f<int,char*,double>("aa",3.0); // expected-warning{{conversion from string literal to 'char *' is deprecated}}
+ f<int,char*>("aa",3.0); // Z is deduced to be double \
+ // expected-warning{{conversion from string literal to 'char *' is deprecated}}
f<int>("aa",3.0); // Y is deduced to be char*, and
// Z is deduced to be double
f("aa",3.0); // expected-error{{no matching}}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p6.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p6.cpp
index 34c3710..f539471 100644
--- a/test/CXX/temp/temp.spec/temp.expl.spec/p6.cpp
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p6.cpp
@@ -54,3 +54,10 @@ void f(Array<String>& v) {
template<> void sort<String>(Array<String>& v); // // expected-error{{after instantiation}}
template<> void sort<>(Array<char*>& v); // OK: sort<char*> not yet used
+
+namespace PR6160 {
+ template<typename T> void f(T);
+ template<> void f(int);
+ extern template void f(int);
+ template<> void f(int) { }
+}
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p4.cpp b/test/CXX/temp/temp.spec/temp.explicit/p4.cpp
index f292b5a..2b85213 100644
--- a/test/CXX/temp/temp.spec/temp.explicit/p4.cpp
+++ b/test/CXX/temp/temp.spec/temp.explicit/p4.cpp
@@ -30,3 +30,19 @@ template long X0<long>::value;
template<> struct X0<double>;
template struct X0<double>;
+
+// PR 6458
+namespace test0 {
+ template <class T> class foo {
+ int compare(T x, T y);
+ };
+
+ template <> int foo<char>::compare(char x, char y);
+ template <class T> int foo<T>::compare(T x, T y) {
+ // invalid at T=char; if we get a diagnostic here, we're
+ // inappropriately instantiating this template.
+ void *ptr = x;
+ }
+ extern template class foo<char>;
+ template class foo<char>;
+}
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p6.cpp b/test/CXX/temp/temp.spec/temp.explicit/p6.cpp
index 44ce41b..1382272 100644
--- a/test/CXX/temp/temp.spec/temp.explicit/p6.cpp
+++ b/test/CXX/temp/temp.spec/temp.explicit/p6.cpp
@@ -12,3 +12,24 @@ template<typename T, typename U> void f0(T, U*) { }
template void f0<int>(int, float*);
template void f0<>(double, float*);
+
+template<typename T> struct hash { };
+struct S {
+ bool operator==(const S&) const { return false; }
+};
+
+template<typename T> struct Hash_map {
+ void Method(const T& x) { h(x); }
+ hash<T> h;
+};
+
+Hash_map<S> *x;
+const Hash_map<S> *foo() {
+ return x;
+}
+
+template<> struct hash<S> {
+ int operator()(const S& k) const {
+ return 0;
+ }
+};
diff --git a/test/CodeGen/2010-02-16-DbgScopes.c b/test/CodeGen/2010-02-16-DbgScopes.c
new file mode 100644
index 0000000..b11f920
--- /dev/null
+++ b/test/CodeGen/2010-02-16-DbgScopes.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -emit-llvm -g < %s | grep lexical | count 5
+// Test to check number of lexical scope identified in debug info.
+
+extern int bar();
+extern void foobar();
+void foo(int s) {
+ unsigned loc = 0;
+ if (s) {
+ if (bar()) {
+ foobar();
+ }
+ } else {
+ loc = 1;
+ if (bar()) {
+ loc = 2;
+ }
+ }
+}
diff --git a/test/CodeGen/2010-02-18-Dbg-VectorType.c b/test/CodeGen/2010-02-18-Dbg-VectorType.c
new file mode 100644
index 0000000..eb17d11
--- /dev/null
+++ b/test/CodeGen/2010-02-18-Dbg-VectorType.c
@@ -0,0 +1,9 @@
+// RUN: %clang -emit-llvm -S -O0 -g %s -o - | grep DW_TAG_typedef | grep float4
+typedef float float4 __attribute__((vector_size(16)));
+
+int main(){
+ volatile float4 x = (float4) { 0.0f, 1.0f, 2.0f, 3.0f };
+ x += x;
+ return 0;
+}
+
diff --git a/test/CodeGen/attributes.c b/test/CodeGen/attributes.c
index 770ce76..4fdf1a5 100644
--- a/test/CodeGen/attributes.c
+++ b/test/CodeGen/attributes.c
@@ -30,6 +30,12 @@ int t12 __attribute__((section("SECT")));
void __t8() {}
void t9() __attribute__((weak, alias("__t8")));
+static void t22(void) __attribute__((weakref("t8")));
+// CHECK: @t22 = alias weak void ()* @t8
+
+static void t23(void) __attribute__((weakref, alias("t8")));
+// CHECK: @t23 = alias weak void ()* @t8
+
// CHECK: declare extern_weak i32 @t15()
int __attribute__((weak_import)) t15(void);
int t17() {
diff --git a/test/CodeGen/blocksignature.c b/test/CodeGen/blocksignature.c
new file mode 100644
index 0000000..6ed8750
--- /dev/null
+++ b/test/CodeGen/blocksignature.c
@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 -fblocks -triple x86_64-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X64
+// RUN: %clang_cc1 -fblocks -triple i686-apple-darwin9 %s -emit-llvm -o - | FileCheck %s -check-prefix=X32
+
+// X64: @.str = private constant [6 x i8] c"v8@?0\00"
+// X64: @__block_literal_global = internal constant %1 { i8** @_NSConcreteGlobalBlock, i32 1342177280,
+// X64: @.str1 = private constant [12 x i8] c"i16@?0c8f12\00"
+// X64: store i32 1073741824, i32*
+
+// X32: @.str = private constant [6 x i8] c"v4@?0\00"
+// X32: @__block_literal_global = internal constant %1 { i8** @_NSConcreteGlobalBlock, i32 1342177280,
+// X32: @.str1 = private constant [11 x i8] c"i12@?0c4f8\00"
+// X32: store i32 1073741824, i32*
+
+// rdar://7635294
+
+
+int globalInt;
+void (^global)(void) = ^{ ++globalInt; };
+
+
+void foo(int param) {
+ extern int rand(void);
+ extern void rand_r(int (^b)(char x, float y)); // name a function present at runtime
+ while (param--)
+ rand_r(^(char x, float y){ return x + (int)y + param + rand(); }); // generate a local block binding param
+}
+
+#if 0
+#include <stdio.h>
+enum {
+ BLOCK_HAS_COPY_DISPOSE = (1 << 25),
+ BLOCK_HAS_CXX_OBJ = (1 << 26),
+ BLOCK_IS_GLOBAL = (1 << 28),
+ BLOCK_HAS_DESCRIPTOR = (1 << 29),
+ BLOCK_HAS_OBJC_TYPE = (1 << 30)
+};
+
+struct block_descriptor_big {
+ unsigned long int reserved;
+ unsigned long int size;
+ void (*copy)(void *dst, void *src); // conditional on BLOCK_HAS_COPY_DISPOSE
+ void (*dispose)(void *); // conditional on BLOCK_HAS_COPY_DISPOSE
+ const char *signature; // conditional on BLOCK_HAS_OBJC
+ const char *layout; // conditional on BLOCK_HAS_OBJC
+};
+struct block_descriptor_small {
+ unsigned long int reserved;
+ unsigned long int size;
+ const char *signature; // conditional on BLOCK_HAS_OBJC
+ const char *layout; // conditional on BLOCK_HAS_OBJC
+};
+
+struct block_layout_abi { // can't change
+ void *isa;
+ int flags;
+ int reserved;
+ void (*invoke)(void *, ...);
+ struct block_descriptor_big *descriptor;
+};
+
+const char *getBlockSignature(void *block) {
+ struct block_layout_abi *layout = (struct block_layout_abi *)block;
+ if ((layout->flags & BLOCK_HAS_OBJC_TYPE) != BLOCK_HAS_OBJC_TYPE) return NULL;
+ if (layout->flags & BLOCK_HAS_COPY_DISPOSE)
+ return layout->descriptor->signature;
+ else
+ return ((struct block_descriptor_small *)layout->descriptor)->signature;
+}
+
+
+
+int main(int argc, char *argv[]) {
+ printf("desired global flags: %d\n", BLOCK_IS_GLOBAL | BLOCK_HAS_OBJC_TYPE);
+ printf("desired stack flags: %d\n", BLOCK_HAS_OBJC_TYPE);
+
+ printf("types for global: %s\n", getBlockSignature(global));
+ printf("types for local: %s\n", getBlockSignature(^int(char x, float y) { return (int)(y + x); }));
+ return 0;
+}
+
+/*
+x86_64
+desired global flags: 1342177280
+desired stack flags: 1073741824
+types for global: v8@?0
+types for local: i16@?0c8f12
+
+i386
+desired global flags: 1342177280
+desired stack flags: 1073741824
+types for global: v4@?0
+types for local: i12@?0c4f8
+*/
+#endif
diff --git a/test/CodeGen/builtins.c b/test/CodeGen/builtins.c
index 4fa4785..417ca7d 100644
--- a/test/CodeGen/builtins.c
+++ b/test/CodeGen/builtins.c
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -emit-llvm -o %t %s
// RUN: not grep __builtin %t
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple x86_64-darwin-apple | FileCheck %s
int printf(const char *, ...);
@@ -9,11 +10,17 @@ void p(char *str, int x) {
void q(char *str, double x) {
printf("%s: %f\n", str, x);
}
+void r(char *str, void *ptr) {
+ printf("%s: %p\n", str, ptr);
+}
+
+int random(void);
int main() {
int N = random();
#define P(n,args) p(#n #args, __builtin_##n args)
#define Q(n,args) q(#n #args, __builtin_##n args)
+#define R(n,args) r(#n #args, __builtin_##n args)
#define V(n,args) p(#n #args, (__builtin_##n args, 0))
P(types_compatible_p, (int, float));
P(choose_expr, (0, 10, 20));
@@ -110,16 +117,48 @@ int main() {
// FIXME
// V(clear_cache, (&N, &N+1));
V(trap, ());
- P(extract_return_addr, (&N));
+ R(extract_return_addr, (&N));
return 0;
}
-void strcat() {}
-
void foo() {
__builtin_strcat(0, 0);
}
+// CHECK: define void @bar(
+void bar() {
+ float f;
+ double d;
+ long double ld;
+
+ // LLVM's hex representation of float constants is really unfortunate;
+ // basically it does a float-to-double "conversion" and then prints the
+ // hex form of that. That gives us wierd artifacts like exponents
+ // that aren't numerically similar to the original exponent and
+ // significand bit-patterns that are offset by three bits (because
+ // the exponent was expanded from 8 bits to 11).
+ //
+ // 0xAE98 == 1010111010011000
+ // 0x15D3 == 1010111010011
+
+ f = __builtin_huge_valf(); // CHECK: float 0x7FF0000000000000
+ d = __builtin_huge_val(); // CHECK: double 0x7FF0000000000000
+ ld = __builtin_huge_vall(); // CHECK: x86_fp80 0xK7FFF8000000000000000
+ f = __builtin_nanf(""); // CHECK: float 0x7FF8000000000000
+ d = __builtin_nan(""); // CHECK: double 0x7FF8000000000000
+ ld = __builtin_nanl(""); // CHECK: x86_fp80 0xK7FFFC000000000000000
+ f = __builtin_nanf("0xAE98"); // CHECK: float 0x7FF815D300000000
+ d = __builtin_nan("0xAE98"); // CHECK: double 0x7FF800000000AE98
+ ld = __builtin_nanl("0xAE98"); // CHECK: x86_fp80 0xK7FFFC00000000000AE98
+ f = __builtin_nansf(""); // CHECK: float 0x7FF4000000000000
+ d = __builtin_nans(""); // CHECK: double 0x7FF4000000000000
+ ld = __builtin_nansl(""); // CHECK: x86_fp80 0xK7FFFA000000000000000
+ f = __builtin_nansf("0xAE98"); // CHECK: float 0x7FF015D300000000
+ d = __builtin_nans("0xAE98"); // CHECK: double 0x7FF000000000AE98
+ ld = __builtin_nansl("0xAE98");// CHECK: x86_fp80 0xK7FFF800000000000AE98
+
+}
+// CHECK: }
diff --git a/test/CodeGen/cast-emit.c b/test/CodeGen/cast-emit.c
new file mode 100644
index 0000000..4e33fa3
--- /dev/null
+++ b/test/CodeGen/cast-emit.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
+
+typedef union {
+ int i;
+ float f;
+} MyUnion;
+void unionf(MyUnion a);
+void uniontest(float a) {
+ f((MyUnion)1.0f);
+// CHECK: store float 1.000000e+00
+}
+
diff --git a/test/CodeGen/dllimport-dllexport.c b/test/CodeGen/dllimport-dllexport.c
index c7c2420..c187503 100644
--- a/test/CodeGen/dllimport-dllexport.c
+++ b/test/CodeGen/dllimport-dllexport.c
@@ -1,7 +1,12 @@
-// RUN: %clang_cc1 -emit-llvm < %s -o %t
-// RUN: grep 'dllexport' %t | count 1
-// RUN: not grep 'dllimport' %t
+// RUN: %clang_cc1 -triple i386-mingw32 -emit-llvm < %s | FileCheck %s
void __attribute__((dllimport)) foo1();
void __attribute__((dllexport)) foo1(){}
+// CHECK: define dllexport void @foo1
void __attribute__((dllexport)) foo2();
+
+// PR6269
+__declspec(dllimport) void foo3();
+__declspec(dllexport) void foo3(){}
+// CHECK: define dllexport void @foo3
+__declspec(dllexport) void foo4();
diff --git a/test/CodeGen/extern-inline.c b/test/CodeGen/extern-inline.c
new file mode 100644
index 0000000..5dd9bfd
--- /dev/null
+++ b/test/CodeGen/extern-inline.c
@@ -0,0 +1,25 @@
+// RUN: %clang -S -emit-llvm -std=gnu89 -o - %s | FileCheck %s
+// PR5253
+
+// If an extern inline function is redefined, functions should call the
+// redefinition.
+extern inline int f(int a) {return a;}
+int g(void) {return f(0);}
+// CHECK: call i32 @f
+int f(int b) {return 1+b;}
+// CHECK: load i32* %{{.*}}
+// CHECK: add nsw i32 1, %{{.*}}
+int h(void) {return f(1);}
+// CHECK: call i32 @f
+
+// It shouldn't matter if the function was redefined static.
+extern inline int f2(int a, int b) {return a+b;}
+int g2(void) {return f2(0,1);}
+// CHECK: call i32 @f2
+static int f2(int a, int b) {return a*b;}
+// CHECK: load i32* %{{.*}}
+// CHECK: load i32* %{{.*}}
+// CHECK: mul i32 %{{.*}}, %{{.*}}
+int h2(void) {return f2(1,2);}
+// CHECK: call i32 @f2
+
diff --git a/test/CodeGen/functions.c b/test/CodeGen/functions.c
index cb9a4ef..5629ef5 100644
--- a/test/CodeGen/functions.c
+++ b/test/CodeGen/functions.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -emit-llvm -o %t
+// RUN: %clang_cc1 %s -emit-llvm -o - -verify | FileCheck %s
int g();
@@ -19,22 +19,31 @@ void test3(T f) {
int a(int);
int a() {return 1;}
-// RUN: grep 'define void @f0()' %t
void f0() {}
+// CHECK: define void @f0()
void f1();
-// RUN: grep 'call void @f1()' %t
void f2(void) {
+// CHECK: call void @f1()
f1(1, 2, 3);
}
-// RUN: grep 'define void @f1()' %t
+// CHECK: define void @f1()
void f1() {}
-// RUN: grep 'define .* @f3' %t | not grep -F '...'
+// CHECK: define {{.*}} @f3{{\(\)|\(.*sret.*\)}}
struct foo { int X, Y, Z; } f3() {
while (1) {}
}
// PR4423 - This shouldn't crash in codegen
void f4() {}
-void f5() { f4(42); }
+void f5() { f4(42); } //expected-warning {{too many arguments}}
+
+// Qualifiers on parameter types shouldn't make a difference.
+static void f6(const float f, const float g) {
+}
+void f7(float f, float g) {
+ f6(f, g);
+// CHECK: define void @f7(float{{.*}}, float{{.*}})
+// CHECK: call void @f6(float{{.*}}, float{{.*}})
+}
diff --git a/test/CodeGenCXX/alloca-align.cpp b/test/CodeGenCXX/alloca-align.cpp
index de6b34d..b70e366 100644
--- a/test/CodeGenCXX/alloca-align.cpp
+++ b/test/CodeGenCXX/alloca-align.cpp
@@ -1,12 +1,28 @@
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
-//
-// CHECK: alloca %struct.MemsetRange, align 16
-struct MemsetRange {
+struct s0 {
int Start, End;
unsigned Alignment;
int TheStores __attribute__((aligned(16)));
};
-void foobar() {
- (void) MemsetRange();
+
+// CHECK: define void @f0
+// CHECK: alloca %struct.s0, align 16
+extern "C" void f0() {
+ (void) s0();
+}
+
+// CHECK: define void @f1
+// CHECK: alloca %struct.s0, align 16
+extern "C" void f1() {
+ (void) (struct s0) { 0, 0, 0, 0 };
+}
+
+// CHECK: define i64 @f2
+// CHECK: alloca %struct.s1, align 2
+struct s1 { short x; short y; };
+extern "C" struct s1 f2(int a, struct s1 *x, struct s1 *y) {
+ if (a)
+ return *x;
+ return *y;
}
diff --git a/test/CodeGenCXX/constructors.cpp b/test/CodeGenCXX/constructors.cpp
new file mode 100644
index 0000000..2c95c91
--- /dev/null
+++ b/test/CodeGenCXX/constructors.cpp
@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - | FileCheck %s
+
+struct Member { int x; Member(); Member(int); Member(const Member &); };
+struct VBase { int x; VBase(); VBase(int); VBase(const VBase &); };
+
+struct ValueClass {
+ ValueClass(int x, int y) : x(x), y(y) {}
+ int x;
+ int y;
+}; // subject to ABI trickery
+
+
+
+/* Test basic functionality. */
+class A {
+ A(struct Undeclared &);
+ A(ValueClass);
+ Member mem;
+};
+
+A::A(struct Undeclared &ref) : mem(0) {}
+
+// Check that delegation works.
+// CHECK: define void @_ZN1AC1ER10Undeclared(
+// CHECK: call void @_ZN1AC2ER10Undeclared(
+
+// CHECK: define void @_ZN1AC2ER10Undeclared(
+// CHECK: call void @_ZN6MemberC1Ei(
+
+A::A(ValueClass v) : mem(v.y - v.x) {}
+
+// CHECK: define void @_ZN1AC1E10ValueClass(
+// CHECK: call void @_ZN1AC2E10ValueClass(
+
+// CHECK: define void @_ZN1AC2E10ValueClass(
+// CHECK: call void @_ZN6MemberC1Ei(
+
+
+/* Test that things work for inheritance. */
+struct B : A {
+ B(struct Undeclared &);
+ Member mem;
+};
+
+B::B(struct Undeclared &ref) : A(ref), mem(1) {}
+
+// CHECK: define void @_ZN1BC1ER10Undeclared(
+// CHECK: call void @_ZN1BC2ER10Undeclared(
+
+// CHECK: define void @_ZN1BC2ER10Undeclared(
+// CHECK: call void @_ZN1AC2ER10Undeclared(
+// CHECK: call void @_ZN6MemberC1Ei(
+
+
+
+/* Test that the delegation optimization is disabled for classes with
+ virtual bases (for now). This is necessary because a vbase
+ initializer could access one of the parameter variables by
+ reference. That's a solvable problem, but let's not solve it right
+ now. */
+struct C : virtual A {
+ C(int);
+ Member mem;
+};
+C::C(int x) : A(ValueClass(x, x+1)), mem(x * x) {}
+
+// CHECK: define void @_ZN1CC1Ei(
+// CHECK: call void @_ZN10ValueClassC1Eii(
+// CHECK: call void @_ZN1AC2E10ValueClass(
+// CHECK: call void @_ZN6MemberC1Ei(
+
+// CHECK: define void @_ZN1CC2Ei(
+// CHECK: call void @_ZN6MemberC1Ei(
+
+
+
+/* Test that the delegation optimization is disabled for varargs
+ constructors. */
+struct D : A {
+ D(int, ...);
+ Member mem;
+};
+
+D::D(int x, ...) : A(ValueClass(x, x+1)), mem(x*x) {}
+
+// CHECK: define void @_ZN1DC1Eiz(
+// CHECK: call void @_ZN10ValueClassC1Eii(
+// CHECK: call void @_ZN1AC2E10ValueClass(
+// CHECK: call void @_ZN6MemberC1Ei(
+
+// CHECK: define void @_ZN1DC2Eiz(
+// CHECK: call void @_ZN10ValueClassC1Eii(
+// CHECK: call void @_ZN1AC2E10ValueClass(
+// CHECK: call void @_ZN6MemberC1Ei(
diff --git a/test/CodeGenCXX/default-arguments.cpp b/test/CodeGenCXX/default-arguments.cpp
index 282e5d0..2ed1567 100644
--- a/test/CodeGenCXX/default-arguments.cpp
+++ b/test/CodeGenCXX/default-arguments.cpp
@@ -43,11 +43,7 @@ struct C {
};
// CHECK: define void @_ZN1CC1Ev(
-// CHECK: call void @_ZN2A1C1Ev(
-// CHECK: call void @_ZN2A2C1Ev(
-// CHECK: call void @_ZN1BC1ERK2A1RK2A2(
-// CHECK: call void @_ZN2A2D1Ev
-// CHECK: call void @_ZN2A1D1Ev
+// CHECK: call void @_ZN1CC2Ev(
// CHECK: define void @_ZN1CC2Ev(
// CHECK: call void @_ZN2A1C1Ev(
diff --git a/test/CodeGenCXX/destructors.cpp b/test/CodeGenCXX/destructors.cpp
index 0a7e1e5..d40b174 100644
--- a/test/CodeGenCXX/destructors.cpp
+++ b/test/CodeGenCXX/destructors.cpp
@@ -1,4 +1,11 @@
-// RUN: %clang_cc1 %s -emit-llvm -o -
+// RUN: %clang_cc1 %s -emit-llvm -o - -mconstructor-aliases | FileCheck %s
+
+// CHECK: @_ZN5test01AD1Ev = alias {{.*}} @_ZN5test01AD2Ev
+// CHECK: @_ZN5test11MD2Ev = alias {{.*}} @_ZN5test11AD2Ev
+// CHECK: @_ZN5test11ND2Ev = alias {{.*}} @_ZN5test11AD2Ev
+// CHECK: @_ZN5test11OD2Ev = alias {{.*}} @_ZN5test11AD2Ev
+// CHECK: @_ZN5test11SD2Ev = alias bitcast {{.*}} @_ZN5test11AD2Ev
+
struct A {
int a;
@@ -42,3 +49,101 @@ namespace PR5529 {
B::~B() {}
}
+
+// FIXME: there's a known problem in the codegen here where, if one
+// destructor throws, the remaining destructors aren't run. Fix it,
+// then make this code check for it.
+namespace test0 {
+ void foo();
+ struct VBase { ~VBase(); };
+ struct Base { ~Base(); };
+ struct Member { ~Member(); };
+
+ struct A : Base {
+ Member M;
+ ~A();
+ };
+
+ // The function-try-block won't suppress -mconstructor-aliases here.
+ A::~A() try { } catch (int i) {}
+
+// complete destructor alias tested above
+
+// CHECK: define void @_ZN5test01AD2Ev
+// CHECK: invoke void @_ZN5test06MemberD1Ev
+// CHECK: unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]]
+// CHECK: invoke void @_ZN5test04BaseD2Ev
+// CHECK: unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
+
+ struct B : Base, virtual VBase {
+ Member M;
+ ~B();
+ };
+ B::~B() try { } catch (int i) {}
+ // It will suppress the delegation optimization here, though.
+
+// CHECK: define void @_ZN5test01BD1Ev
+// CHECK: invoke void @_ZN5test06MemberD1Ev
+// CHECK: unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]]
+// CHECK: invoke void @_ZN5test04BaseD2Ev
+// CHECK: unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
+// CHECK: invoke void @_ZN5test05VBaseD2Ev
+// CHECK: unwind label [[VBASE_UNWIND:%[a-zA-Z0-9.]+]]
+
+// CHECK: define void @_ZN5test01BD2Ev
+// CHECK: invoke void @_ZN5test06MemberD1Ev
+// CHECK: unwind label [[MEM_UNWIND:%[a-zA-Z0-9.]+]]
+// CHECK: invoke void @_ZN5test04BaseD2Ev
+// CHECK: unwind label [[BASE_UNWIND:%[a-zA-Z0-9.]+]]
+}
+
+// Test base-class aliasing.
+namespace test1 {
+ struct A { ~A(); char ***m; }; // non-trivial destructor
+ struct B { ~B(); }; // non-trivial destructor
+ struct Empty { }; // trivial destructor, empty
+ struct NonEmpty { int x; }; // trivial destructor, non-empty
+
+ // There must be a definition in this translation unit for the alias
+ // optimization to apply.
+ A::~A() { delete m; }
+
+ struct M : A { ~M(); };
+ M::~M() {} // alias tested above
+
+ struct N : A, Empty { ~N(); };
+ N::~N() {} // alias tested above
+
+ struct O : Empty, A { ~O(); };
+ O::~O() {} // alias tested above
+
+ struct P : NonEmpty, A { ~P(); };
+ P::~P() {} // CHECK: define void @_ZN5test11PD2Ev
+
+ struct Q : A, B { ~Q(); };
+ Q::~Q() {} // CHECK: define void @_ZN5test11QD2Ev
+
+ struct R : A { ~R(); };
+ R::~R() { A a; } // CHECK: define void @_ZN5test11RD2Ev
+
+ struct S : A { ~S(); int x; };
+ S::~S() {} // alias tested above
+
+ struct T : A { ~T(); B x; };
+ T::~T() {} // CHECK: define void @_ZN5test11TD2Ev
+
+ // The VTT parameter prevents this. We could still make this work
+ // for calling conventions that are safe against extra parameters.
+ struct U : A, virtual B { ~U(); };
+ U::~U() {} // CHECK: define void @_ZN5test11UD2Ev
+}
+
+// PR6471
+namespace test2 {
+ struct A { ~A(); char ***m; };
+ struct B : A { ~B(); };
+
+ B::~B() {}
+ // CHECK: define void @_ZN5test21BD2Ev
+ // CHECK: call void @_ZN5test21AD2Ev
+}
diff --git a/test/CodeGenCXX/mangle-subst-std.cpp b/test/CodeGenCXX/mangle-subst-std.cpp
index 913c8f1..062610b 100644
--- a/test/CodeGenCXX/mangle-subst-std.cpp
+++ b/test/CodeGenCXX/mangle-subst-std.cpp
@@ -55,3 +55,9 @@ namespace std
terminate_handler set_terminate(terminate_handler) { return 0; }
}
}
+
+// Make sure we don't treat the following like std::string
+// CHECK: define void @_Z1f12basic_stringIcSt11char_traitsIcESaIcEE
+template<typename, typename, typename> struct basic_string { };
+typedef basic_string<char, std::char_traits<char>, std::allocator<char> > not_string;
+void f(not_string) { }
diff --git a/test/CodeGenCXX/mangle-template.cpp b/test/CodeGenCXX/mangle-template.cpp
index c8296f3..57f30a7 100644
--- a/test/CodeGenCXX/mangle-template.cpp
+++ b/test/CodeGenCXX/mangle-template.cpp
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
-
namespace test1 {
int x;
template <int& D> class T { };
@@ -66,3 +65,42 @@ template <void(A::*)(float)> class T { };
// CHECK-FAIL: void @_ZN5test62f0ENS_1TIXadL_ZNS_1A3im0EfEEEE(
void f0(T<&A::im0> a0) {}
}
+
+namespace test7 {
+ template<typename T>
+ struct meta {
+ static const unsigned value = sizeof(T);
+ };
+
+ template<unsigned> struct int_c {
+ typedef float type;
+ };
+
+ template<typename T>
+ struct X {
+ template<typename U>
+ X(U*, typename int_c<(meta<T>::value + meta<U>::value)>::type *) { }
+ };
+
+ // CHECK: define void @_ZN5test71XIiEC1IdEEPT_PNS_5int_cIXplL_ZNS_4metaIiE5valueEEsrNS6_IS3_EE5valueEE4typeE
+ template X<int>::X(double*, float*);
+}
+
+namespace test8 {
+ template<typename T>
+ struct meta {
+ struct type {
+ static const unsigned value = sizeof(T);
+ };
+ };
+
+ template<unsigned> struct int_c {
+ typedef float type;
+ };
+
+ template<typename T>
+ void f(int_c<meta<T>::type::value>) { }
+
+ // CHECK: define void @_ZN5test81fIiEEvNS_5int_cIXsrNS_4metaIT_E4typeE5valueEEE
+ template void f<int>(int_c<sizeof(int)>);
+}
diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp
index 0718378..e18ca03 100644
--- a/test/CodeGenCXX/mangle.cpp
+++ b/test/CodeGenCXX/mangle.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -fblocks | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -fblocks -std=c++0x | FileCheck %s
struct X { };
struct Y { };
@@ -363,7 +363,7 @@ namespace test0 {
char buffer[1024];
j<A>(buffer);
}
- // CHECK: define linkonce_odr void @_ZN5test01jINS_1AEEEvRAszmecvT__E6buffer_c(
+ // CHECK: define linkonce_odr void @_ZN5test01jINS_1AEEEvRAszdtcvT__E6buffer_c(
}
namespace test1 {
@@ -376,3 +376,41 @@ namespace test1 {
// CHECK: define internal void @_Z27functionWithInternalLinkagev()
static void functionWithInternalLinkage() { }
void g() { functionWithInternalLinkage(); }
+
+namespace test2 {
+ template <class T> decltype(((T*) 0)->member) read_member(T& obj) {
+ return obj.member;
+ }
+
+ struct A { int member; } obj;
+ int test() {
+ return read_member(obj);
+ }
+
+ // CHECK: define linkonce_odr i32 @_ZN5test211read_memberINS_1AEEEDtptcvPT_Li0E6memberERS2_(
+}
+
+namespace test3 {
+ struct AmbiguousBase { int ab; };
+ struct Path1 : AmbiguousBase { float p; };
+ struct Path2 : AmbiguousBase { double p; };
+ struct Derived : Path1, Path2 { };
+
+ //template <class T> decltype(((T*) 0)->Path1::ab) get_ab_1(T &ref) { return ref.Path1::ab; }
+ //template <class T> decltype(((T*) 0)->Path2::ab) get_ab_2(T &ref) { return ref.Path2::ab; }
+
+ // define linkonce_odr float @_ZN5test37get_p_1INS_7DerivedEEEDtptcvPT_Li0E5Path11pERS2_(
+ template <class T> decltype(((T*) 0)->Path1::p) get_p_1(T &ref) { return ref.Path1::p; }
+
+ // define linkonce_odr double @_ZN5test37get_p_1INS_7DerivedEEEDtptcvPT_Li0E5Path21pERS2_(
+ template <class T> decltype(((T*) 0)->Path2::p) get_p_2(T &ref) { return ref.Path2::p; }
+
+ Derived obj;
+ void test() {
+ // FIXME: uncomment these when we support diamonds competently
+ //get_ab_1(obj);
+ //get_ab_2(obj);
+ get_p_1(obj);
+ get_p_2(obj);
+ }
+}
diff --git a/test/CodeGenCXX/virtual-base-destructor-call.cpp b/test/CodeGenCXX/virtual-base-destructor-call.cpp
index 1ee598a..b6e85e2 100644
--- a/test/CodeGenCXX/virtual-base-destructor-call.cpp
+++ b/test/CodeGenCXX/virtual-base-destructor-call.cpp
@@ -16,4 +16,36 @@ basic_iostream<char> res;
int main() {
}
-// CHECK: call void @_ZN9basic_iosD2Ev
+// basic_iostream's complete dtor calls its base dtor, then its
+// virtual base's dtor.
+// CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED1Ev
+// CHECK: call void @_ZN14basic_iostreamIcED2Ev
+// CHECK: call void @_ZN9basic_iosD2Ev
+
+// basic_iostream's deleting dtor calls its complete dtor, then
+// operator delete().
+// CHECK: define linkonce_odr void @_ZN14basic_iostreamIcED0Ev
+// CHECK: call void @_ZN14basic_iostreamIcED1Ev
+// CHECK: call void @_ZdlPv
+
+// basic_istream's complete dtor calls the base dtor,
+// then its virtual base's base dtor.
+// CHECK: define linkonce_odr void @_ZN13basic_istreamIcED1Ev
+// CHECK: call void @_ZN13basic_istreamIcED2Ev
+// CHECK: call void @_ZN9basic_iosD2Ev
+
+// basic_istream's deleting dtor calls the complete dtor, then
+// operator delete().
+// CHECK: define linkonce_odr void @_ZN13basic_istreamIcED0Ev
+// 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
+// CHECK: }
diff --git a/test/CodeGenCXX/virtual-bases.cpp b/test/CodeGenCXX/virtual-bases.cpp
index 200f21a..6277175 100644
--- a/test/CodeGenCXX/virtual-bases.cpp
+++ b/test/CodeGenCXX/virtual-bases.cpp
@@ -1,10 +1,10 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 -mconstructor-aliases | FileCheck %s
struct A {
A();
};
-// CHECK: define void @_ZN1AC1Ev(%struct.A* %this)
+// CHECK: @_ZN1AC1Ev = alias {{.*}} @_ZN1AC2Ev
// CHECK: define void @_ZN1AC2Ev(%struct.A* %this)
A::A() { }
diff --git a/test/CodeGenCXX/virtual-destructor-calls.cpp b/test/CodeGenCXX/virtual-destructor-calls.cpp
index 01ca144..c5b9262 100644
--- a/test/CodeGenCXX/virtual-destructor-calls.cpp
+++ b/test/CodeGenCXX/virtual-destructor-calls.cpp
@@ -1,24 +1,48 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin10 -mconstructor-aliases | FileCheck %s
+
+struct Member {
+ ~Member();
+};
struct A {
virtual ~A();
};
struct B : A {
+ Member m;
virtual ~B();
};
-// Complete dtor.
-// CHECK: define void @_ZN1BD1Ev
-// CHECK: call void @_ZN1AD2Ev
+// Complete dtor: just an alias because there are no virtual bases.
+// CHECK: @_ZN1BD1Ev = alias {{.*}} @_ZN1BD2Ev
-// Deleting dtor.
+// (aliases from C)
+// CHECK: @_ZN1CD1Ev = alias {{.*}} @_ZN1CD2Ev
+// CHECK: @_ZN1CD2Ev = alias bitcast {{.*}} @_ZN1BD2Ev
+
+// Deleting dtor: defers to the complete dtor.
// CHECK: define void @_ZN1BD0Ev
-// CHECK: call void @_ZN1AD2Ev
-// check: call void @_ZdlPv
+// CHECK: call void @_ZN1BD1Ev
+// CHECK: call void @_ZdlPv
-// Base dtor.
+// Base dtor: actually calls A's base dtor.
// CHECK: define void @_ZN1BD2Ev
+// CHECK: call void @_ZN6MemberD1Ev
// CHECK: call void @_ZN1AD2Ev
B::~B() { }
+
+struct C : B {
+ ~C();
+};
+
+C::~C() { }
+
+// Complete dtor: just an alias (checked above).
+
+// Deleting dtor: defers to the complete dtor.
+// CHECK: define void @_ZN1CD0Ev
+// CHECK: call void @_ZN1CD1Ev
+// CHECK: call void @_ZdlPv
+
+// Base dtor: just an alias to B's base dtor.
diff --git a/test/CodeGenCXX/vtable-layout-abi-examples.cpp b/test/CodeGenCXX/vtable-layout-abi-examples.cpp
new file mode 100644
index 0000000..2c6b7a4
--- /dev/null
+++ b/test/CodeGenCXX/vtable-layout-abi-examples.cpp
@@ -0,0 +1,189 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm-only -fdump-vtable-layouts 2>&1 | FileCheck %s
+
+/// Examples from the Itanium C++ ABI specification.
+/// http://www.codesourcery.com/public/cxx-abi/
+
+namespace Test1 {
+
+// This is from http://www.codesourcery.com/public/cxx-abi/cxx-vtable-ex.html
+
+// CHECK: Vtable for 'Test1::A' (5 entries).
+// CHECK-NEXT: 0 | offset_to_top (0)
+// CHECK-NEXT: 1 | Test1::A RTTI
+// CHECK-NEXT: -- (Test1::A, 0) vtable address --
+// CHECK-NEXT: 2 | void Test1::A::f()
+// CHECK-NEXT: 3 | void Test1::A::g()
+// CHECK-NEXT: 4 | void Test1::A::h()
+struct A {
+ virtual void f ();
+ virtual void g ();
+ virtual void h ();
+ int ia;
+};
+void A::f() {}
+
+// CHECK: Vtable for 'Test1::B' (13 entries).
+// CHECK-NEXT: 0 | vbase_offset (16)
+// CHECK-NEXT: 1 | offset_to_top (0)
+// CHECK-NEXT: 2 | Test1::B RTTI
+// CHECK-NEXT: -- (Test1::B, 0) vtable address --
+// CHECK-NEXT: 3 | void Test1::B::f()
+// CHECK-NEXT: 4 | void Test1::B::h()
+// CHECK-NEXT: 5 | vcall_offset (-16)
+// CHECK-NEXT: 6 | vcall_offset (0)
+// CHECK-NEXT: 7 | vcall_offset (-16)
+// CHECK-NEXT: 8 | offset_to_top (-16)
+// CHECK-NEXT: 9 | Test1::B RTTI
+// CHECK-NEXT: -- (Test1::A, 16) vtable address --
+// CHECK-NEXT: 10 | void Test1::B::f()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT: 11 | void Test1::A::g()
+// CHECK-NEXT: 12 | void Test1::B::h()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -40 vcall offset offset]
+struct B: public virtual A {
+ void f ();
+ void h ();
+ int ib;
+};
+void B::f() {}
+
+// CHECK: Vtable for 'Test1::C' (13 entries).
+// CHECK-NEXT: 0 | vbase_offset (16)
+// CHECK-NEXT: 1 | offset_to_top (0)
+// CHECK-NEXT: 2 | Test1::C RTTI
+// CHECK-NEXT: -- (Test1::C, 0) vtable address --
+// CHECK-NEXT: 3 | void Test1::C::g()
+// CHECK-NEXT: 4 | void Test1::C::h()
+// CHECK-NEXT: 5 | vcall_offset (-16)
+// CHECK-NEXT: 6 | vcall_offset (-16)
+// CHECK-NEXT: 7 | vcall_offset (0)
+// CHECK-NEXT: 8 | offset_to_top (-16)
+// CHECK-NEXT: 9 | Test1::C RTTI
+// CHECK-NEXT: -- (Test1::A, 16) vtable address --
+// CHECK-NEXT: 10 | void Test1::A::f()
+// CHECK-NEXT: 11 | void Test1::C::g()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
+// CHECK-NEXT: 12 | void Test1::C::h()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -40 vcall offset offset]
+struct C: public virtual A {
+ void g ();
+ void h ();
+ int ic;
+};
+void C::g() {}
+
+// CHECK: Vtable for 'Test1::D' (18 entries).
+// CHECK-NEXT: 0 | vbase_offset (32)
+// CHECK-NEXT: 1 | offset_to_top (0)
+// CHECK-NEXT: 2 | Test1::D RTTI
+// CHECK-NEXT: -- (Test1::B, 0) vtable address --
+// CHECK-NEXT: -- (Test1::D, 0) vtable address --
+// CHECK-NEXT: 3 | void Test1::B::f()
+// CHECK-NEXT: 4 | void Test1::D::h()
+// CHECK-NEXT: 5 | vbase_offset (16)
+// CHECK-NEXT: 6 | offset_to_top (-16)
+// CHECK-NEXT: 7 | Test1::D RTTI
+// CHECK-NEXT: -- (Test1::C, 16) vtable address --
+// CHECK-NEXT: 8 | void Test1::C::g()
+// CHECK-NEXT: 9 | void Test1::D::h()
+// CHECK-NEXT: [this adjustment: -16 non-virtual]
+// CHECK-NEXT: 10 | vcall_offset (-32)
+// CHECK-NEXT: 11 | vcall_offset (-16)
+// CHECK-NEXT: 12 | vcall_offset (-32)
+// CHECK-NEXT: 13 | offset_to_top (-32)
+// CHECK-NEXT: 14 | Test1::D RTTI
+// CHECK-NEXT: -- (Test1::A, 32) vtable address --
+// CHECK-NEXT: 15 | void Test1::B::f()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT: 16 | void Test1::C::g()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
+// CHECK-NEXT: 17 | void Test1::D::h()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -40 vcall offset offset]
+struct D: public B, public C {
+ void h ();
+ int id;
+};
+void D::h() { }
+
+struct X {
+ int ix;
+ virtual void x();
+};
+
+// CHECK: Vtable for 'Test1::E' (24 entries).
+// CHECK-NEXT: 0 | vbase_offset (56)
+// CHECK-NEXT: 1 | offset_to_top (0)
+// CHECK-NEXT: 2 | Test1::E RTTI
+// CHECK-NEXT: -- (Test1::E, 0) vtable address --
+// CHECK-NEXT: -- (Test1::X, 0) vtable address --
+// CHECK-NEXT: 3 | void Test1::X::x()
+// CHECK-NEXT: 4 | void Test1::E::f()
+// CHECK-NEXT: 5 | void Test1::E::h()
+// CHECK-NEXT: 6 | vbase_offset (40)
+// CHECK-NEXT: 7 | offset_to_top (-16)
+// CHECK-NEXT: 8 | Test1::E RTTI
+// CHECK-NEXT: -- (Test1::B, 16) vtable address --
+// CHECK-NEXT: -- (Test1::D, 16) vtable address --
+// CHECK-NEXT: 9 | void Test1::E::f()
+// CHECK-NEXT: [this adjustment: -16 non-virtual]
+// CHECK-NEXT: 10 | void Test1::E::h()
+// CHECK-NEXT: [this adjustment: -16 non-virtual]
+// CHECK-NEXT: 11 | vbase_offset (24)
+// CHECK-NEXT: 12 | offset_to_top (-32)
+// CHECK-NEXT: 13 | Test1::E RTTI
+// CHECK-NEXT: -- (Test1::C, 32) vtable address --
+// CHECK-NEXT: 14 | void Test1::C::g()
+// CHECK-NEXT: 15 | void Test1::E::h()
+// CHECK-NEXT: [this adjustment: -32 non-virtual]
+// CHECK-NEXT: 16 | vcall_offset (-56)
+// CHECK-NEXT: 17 | vcall_offset (-24)
+// CHECK-NEXT: 18 | vcall_offset (-56)
+// CHECK-NEXT: 19 | offset_to_top (-56)
+// CHECK-NEXT: 20 | Test1::E RTTI
+// CHECK-NEXT: -- (Test1::A, 56) vtable address --
+// CHECK-NEXT: 21 | void Test1::E::f()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT: 22 | void Test1::C::g()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
+// CHECK-NEXT: 23 | void Test1::E::h()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -40 vcall offset offset]
+struct E : X, D {
+ int ie;
+ void f();
+ void h ();
+};
+void E::f() { }
+
+}
+
+namespace Test2 {
+
+// From http://www.codesourcery.com/public/cxx-abi/abi.html#class-types.
+
+struct A { virtual void f(); };
+struct B : virtual public A { int i; };
+struct C : virtual public A { int j; };
+
+// CHECK: Vtable for 'Test2::D' (11 entries).
+// CHECK-NEXT: 0 | vbase_offset (0)
+// CHECK-NEXT: 1 | vcall_offset (0)
+// CHECK-NEXT: 2 | offset_to_top (0)
+// CHECK-NEXT: 3 | Test2::D RTTI
+// CHECK-NEXT: -- (Test2::A, 0) vtable address --
+// CHECK-NEXT: -- (Test2::B, 0) vtable address --
+// CHECK-NEXT: -- (Test2::D, 0) vtable address --
+// CHECK-NEXT: 4 | void Test2::A::f()
+// CHECK-NEXT: 5 | void Test2::D::d()
+// CHECK-NEXT: 6 | vbase_offset (-16)
+// CHECK-NEXT: 7 | vcall_offset (-16)
+// CHECK-NEXT: 8 | offset_to_top (-16)
+// CHECK-NEXT: 9 | Test2::D RTTI
+// CHECK-NEXT: -- (Test2::A, 16) vtable address --
+// CHECK-NEXT: -- (Test2::C, 16) vtable address --
+// CHECK-NEXT: 10 | [unused] void Test2::A::f()
+struct D : public B, public C {
+ virtual void d();
+};
+void D::d() { }
+
+}
diff --git a/test/CodeGenCXX/vtable-layout-extreme.cpp b/test/CodeGenCXX/vtable-layout-extreme.cpp
new file mode 100644
index 0000000..14e7879
--- /dev/null
+++ b/test/CodeGenCXX/vtable-layout-extreme.cpp
@@ -0,0 +1,210 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm-only -fdump-vtable-layouts 2>&1 | FileCheck %s
+
+// A collection of big class hierarchies and their vtables.
+
+namespace Test1 {
+
+class C0
+{
+};
+class C1
+ : virtual public C0
+{
+ int k0;
+};
+class C2
+ : public C0
+ , virtual public C1
+{
+ int k0;
+};
+class C3
+ : virtual public C0
+ , virtual public C1
+ , public C2
+{
+ int k0;
+ int k1;
+ int k2;
+ int k3;
+};
+class C4
+ : public C2
+ , virtual public C3
+ , public C0
+{
+ int k0;
+};
+class C5
+ : public C0
+ , virtual public C4
+ , public C2
+ , public C1
+ , virtual public C3
+{
+ int k0;
+};
+class C6
+ : virtual public C3
+ , public C0
+ , public C5
+ , public C4
+ , public C1
+{
+ int k0;
+};
+class C7
+ : virtual public C5
+ , virtual public C6
+ , virtual public C3
+ , public C4
+ , virtual public C2
+{
+ int k0;
+ int k1;
+};
+class C8
+ : public C7
+ , public C5
+ , public C3
+ , virtual public C4
+ , public C1
+ , public C2
+{
+ int k0;
+ int k1;
+};
+
+// CHECK: Vtable for 'Test1::C9' (87 entries).
+// CHECK-NEXT: 0 | vbase_offset (344)
+// CHECK-NEXT: 1 | vbase_offset (312)
+// CHECK-NEXT: 2 | vbase_offset (184)
+// CHECK-NEXT: 3 | vbase_offset (168)
+// CHECK-NEXT: 4 | vbase_offset (120)
+// CHECK-NEXT: 5 | vbase_offset (48)
+// CHECK-NEXT: 6 | vbase_offset (148)
+// CHECK-NEXT: 7 | vbase_offset (152)
+// CHECK-NEXT: 8 | offset_to_top (0)
+// CHECK-NEXT: 9 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 0) vtable address --
+// CHECK-NEXT: -- (Test1::C9, 0) vtable address --
+// CHECK-NEXT: 10 | void Test1::C9::f()
+// CHECK-NEXT: 11 | vbase_offset (104)
+// CHECK-NEXT: 12 | vbase_offset (132)
+// CHECK-NEXT: 13 | vbase_offset (136)
+// CHECK-NEXT: 14 | offset_to_top (-16)
+// CHECK-NEXT: 15 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 16) vtable address --
+// CHECK-NEXT: -- (Test1::C4, 16) vtable address --
+// CHECK-NEXT: 16 | vbase_offset (72)
+// CHECK-NEXT: 17 | vbase_offset (120)
+// CHECK-NEXT: 18 | vbase_offset (100)
+// CHECK-NEXT: 19 | vbase_offset (104)
+// CHECK-NEXT: 20 | offset_to_top (-48)
+// CHECK-NEXT: 21 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 48) vtable address --
+// CHECK-NEXT: -- (Test1::C5, 48) vtable address --
+// CHECK-NEXT: -- (Test1::C6, 48) vtable address --
+// CHECK-NEXT: 22 | vbase_offset (84)
+// CHECK-NEXT: 23 | offset_to_top (-64)
+// CHECK-NEXT: 24 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C1, 64) vtable address --
+// CHECK-NEXT: 25 | vbase_offset (32)
+// CHECK-NEXT: 26 | vbase_offset (60)
+// CHECK-NEXT: 27 | vbase_offset (64)
+// CHECK-NEXT: 28 | offset_to_top (-88)
+// CHECK-NEXT: 29 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 88) vtable address --
+// CHECK-NEXT: -- (Test1::C4, 88) vtable address --
+// CHECK-NEXT: 30 | vbase_offset (44)
+// CHECK-NEXT: 31 | offset_to_top (-104)
+// CHECK-NEXT: 32 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C1, 104) vtable address --
+// CHECK-NEXT: 33 | vbase_offset (28)
+// CHECK-NEXT: 34 | vbase_offset (32)
+// CHECK-NEXT: 35 | offset_to_top (-120)
+// CHECK-NEXT: 36 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 120) vtable address --
+// CHECK-NEXT: -- (Test1::C3, 120) vtable address --
+// CHECK-NEXT: 37 | vbase_offset (-4)
+// CHECK-NEXT: 38 | offset_to_top (-152)
+// CHECK-NEXT: 39 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C1, 152) vtable address --
+// CHECK-NEXT: 40 | vbase_offset (-48)
+// CHECK-NEXT: 41 | vbase_offset (-20)
+// CHECK-NEXT: 42 | vbase_offset (-16)
+// CHECK-NEXT: 43 | offset_to_top (-168)
+// CHECK-NEXT: 44 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 168) vtable address --
+// CHECK-NEXT: -- (Test1::C4, 168) vtable address --
+// CHECK-NEXT: 45 | vbase_offset (160)
+// CHECK-NEXT: 46 | vbase_offset (-136)
+// CHECK-NEXT: 47 | vbase_offset (-16)
+// CHECK-NEXT: 48 | vbase_offset (128)
+// CHECK-NEXT: 49 | vbase_offset (-64)
+// CHECK-NEXT: 50 | vbase_offset (-36)
+// CHECK-NEXT: 51 | vbase_offset (-32)
+// CHECK-NEXT: 52 | offset_to_top (-184)
+// CHECK-NEXT: 53 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 184) vtable address --
+// CHECK-NEXT: -- (Test1::C4, 184) vtable address --
+// CHECK-NEXT: -- (Test1::C7, 184) vtable address --
+// CHECK-NEXT: -- (Test1::C8, 184) vtable address --
+// CHECK-NEXT: 54 | vbase_offset (-88)
+// CHECK-NEXT: 55 | vbase_offset (-40)
+// CHECK-NEXT: 56 | vbase_offset (-60)
+// CHECK-NEXT: 57 | vbase_offset (-56)
+// CHECK-NEXT: 58 | offset_to_top (-208)
+// CHECK-NEXT: 59 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 208) vtable address --
+// CHECK-NEXT: -- (Test1::C5, 208) vtable address --
+// CHECK-NEXT: 60 | vbase_offset (-76)
+// CHECK-NEXT: 61 | offset_to_top (-224)
+// CHECK-NEXT: 62 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C1, 224) vtable address --
+// CHECK-NEXT: 63 | vbase_offset (-92)
+// CHECK-NEXT: 64 | vbase_offset (-88)
+// CHECK-NEXT: 65 | offset_to_top (-240)
+// CHECK-NEXT: 66 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 240) vtable address --
+// CHECK-NEXT: -- (Test1::C3, 240) vtable address --
+// CHECK-NEXT: 67 | vbase_offset (-124)
+// CHECK-NEXT: 68 | offset_to_top (-272)
+// CHECK-NEXT: 69 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C1, 272) vtable address --
+// CHECK-NEXT: 70 | vbase_offset (-140)
+// CHECK-NEXT: 71 | vbase_offset (-136)
+// CHECK-NEXT: 72 | offset_to_top (-288)
+// CHECK-NEXT: 73 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 288) vtable address --
+// CHECK-NEXT: 74 | vbase_offset (-192)
+// CHECK-NEXT: 75 | vbase_offset (-144)
+// CHECK-NEXT: 76 | vbase_offset (-164)
+// CHECK-NEXT: 77 | vbase_offset (-160)
+// CHECK-NEXT: 78 | offset_to_top (-312)
+// CHECK-NEXT: 79 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C2, 312) vtable address --
+// CHECK-NEXT: -- (Test1::C5, 312) vtable address --
+// CHECK-NEXT: 80 | vbase_offset (-180)
+// CHECK-NEXT: 81 | offset_to_top (-328)
+// CHECK-NEXT: 82 | Test1::C9 RTTI
+// CHECK-NEXT: -- (Test1::C1, 328) vtable address --
+// CHECK-NEXT: 83 | vbase_offset (-196)
+// CHECK-NEXT: 84 | vbase_offset (-192)
+// CHECK-NEXT: 85 | offset_to_top (-344)
+// CHECK-NEXT: 86 | Test1::C9 RTTI
+class C9
+ : virtual public C6
+ , public C2
+ , public C4
+ , virtual public C8
+{
+ int k0;
+ int k1;
+ int k2;
+ int k3;
+ virtual void f();
+};
+void C9::f() { }
+
+}
diff --git a/test/CodeGenCXX/vtable-layout.cpp b/test/CodeGenCXX/vtable-layout.cpp
index 8fbe486..a65af6e 100644
--- a/test/CodeGenCXX/vtable-layout.cpp
+++ b/test/CodeGenCXX/vtable-layout.cpp
@@ -365,3 +365,674 @@ struct B : virtual A1, virtual A2 {
void B::f() { }
}
+
+namespace Test10 {
+
+// Test for a bug where we would not emit secondary vtables for bases
+// of a primary base.
+struct A1 { virtual void a1(); };
+struct A2 { virtual void a2(); };
+
+// CHECK: Vtable for 'Test10::C' (7 entries).
+// CHECK-NEXT: 0 | offset_to_top (0)
+// CHECK-NEXT: 1 | Test10::C RTTI
+// CHECK-NEXT: -- (Test10::A1, 0) vtable address --
+// CHECK-NEXT: -- (Test10::B, 0) vtable address --
+// CHECK-NEXT: -- (Test10::C, 0) vtable address --
+// CHECK-NEXT: 2 | void Test10::A1::a1()
+// CHECK-NEXT: 3 | void Test10::C::f()
+// CHECK-NEXT: 4 | offset_to_top (-8)
+// CHECK-NEXT: 5 | Test10::C RTTI
+// CHECK-NEXT: -- (Test10::A2, 8) vtable address --
+// CHECK-NEXT: 6 | void Test10::A2::a2()
+struct B : A1, A2 {
+ int b;
+};
+
+struct C : B {
+ virtual void f();
+};
+void C::f() { }
+
+}
+
+namespace Test11 {
+
+// Very simple test of vtables for virtual bases.
+struct A1 { int a; };
+struct A2 { int b; };
+
+struct B : A1, virtual A2 {
+ int b;
+};
+
+// CHECK: Vtable for 'Test11::C' (8 entries).
+// CHECK-NEXT: 0 | vbase_offset (24)
+// CHECK-NEXT: 1 | vbase_offset (8)
+// CHECK-NEXT: 2 | offset_to_top (0)
+// CHECK-NEXT: 3 | Test11::C RTTI
+// CHECK-NEXT: -- (Test11::C, 0) vtable address --
+// CHECK-NEXT: 4 | void Test11::C::f()
+// CHECK-NEXT: 5 | vbase_offset (16)
+// CHECK-NEXT: 6 | offset_to_top (-8)
+// CHECK-NEXT: 7 | Test11::C RTTI
+struct C : virtual B {
+ virtual void f();
+};
+void C::f() { }
+
+}
+
+namespace Test12 {
+
+// Test that the right vcall offsets are generated in the right order.
+
+// CHECK: Vtable for 'Test12::B' (19 entries).
+// CHECK-NEXT: 0 | vbase_offset (8)
+// CHECK-NEXT: 1 | offset_to_top (0)
+// CHECK-NEXT: 2 | Test12::B RTTI
+// CHECK-NEXT: -- (Test12::B, 0) vtable address --
+// CHECK-NEXT: 3 | void Test12::B::f()
+// CHECK-NEXT: 4 | void Test12::B::a()
+// CHECK-NEXT: 5 | vcall_offset (32)
+// CHECK-NEXT: 6 | vcall_offset (16)
+// CHECK-NEXT: 7 | vcall_offset (-8)
+// CHECK-NEXT: 8 | vcall_offset (0)
+// CHECK-NEXT: 9 | offset_to_top (-8)
+// CHECK-NEXT: 10 | Test12::B RTTI
+// CHECK-NEXT: -- (Test12::A, 8) vtable address --
+// CHECK-NEXT: -- (Test12::A1, 8) vtable address --
+// CHECK-NEXT: 11 | void Test12::A1::a1()
+// CHECK-NEXT: 12 | void Test12::B::a()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
+// CHECK-NEXT: 13 | offset_to_top (-24)
+// CHECK-NEXT: 14 | Test12::B RTTI
+// CHECK-NEXT: -- (Test12::A2, 24) vtable address --
+// CHECK-NEXT: 15 | void Test12::A2::a2()
+// CHECK-NEXT: 16 | offset_to_top (-40)
+// CHECK-NEXT: 17 | Test12::B RTTI
+// CHECK-NEXT: -- (Test12::A3, 40) vtable address --
+// CHECK-NEXT: 18 | void Test12::A3::a3()
+struct A1 {
+ virtual void a1();
+ int a;
+};
+
+struct A2 {
+ virtual void a2();
+ int a;
+};
+
+struct A3 {
+ virtual void a3();
+ int a;
+};
+
+struct A : A1, A2, A3 {
+ virtual void a();
+ int i;
+};
+
+struct B : virtual A {
+ virtual void f();
+
+ virtual void a();
+};
+void B::f() { }
+
+}
+
+namespace Test13 {
+
+// Test that we don't try to emit a vtable for 'A' twice.
+struct A {
+ virtual void f();
+};
+
+struct B : virtual A {
+ virtual void f();
+};
+
+// CHECK: Vtable for 'Test13::C' (6 entries).
+// CHECK-NEXT: 0 | vbase_offset (0)
+// CHECK-NEXT: 1 | vbase_offset (0)
+// CHECK-NEXT: 2 | vcall_offset (0)
+// CHECK-NEXT: 3 | offset_to_top (0)
+// CHECK-NEXT: 4 | Test13::C RTTI
+// CHECK-NEXT: -- (Test13::A, 0) vtable address --
+// CHECK-NEXT: -- (Test13::B, 0) vtable address --
+// CHECK-NEXT: -- (Test13::C, 0) vtable address --
+// CHECK-NEXT: 5 | void Test13::C::f()
+struct C : virtual B, virtual A {
+ virtual void f();
+};
+void C::f() { }
+
+}
+
+namespace Test14 {
+
+// Verify that we handle A being a non-virtual base of B, which is a virtual base.
+
+struct A {
+ virtual void f();
+};
+
+struct B : A { };
+
+struct C : virtual B { };
+
+// CHECK: Vtable for 'Test14::D' (5 entries).
+// CHECK-NEXT: 0 | vbase_offset (0)
+// CHECK-NEXT: 1 | vcall_offset (0)
+// CHECK-NEXT: 2 | offset_to_top (0)
+// CHECK-NEXT: 3 | Test14::D RTTI
+// CHECK-NEXT: -- (Test14::A, 0) vtable address --
+// CHECK-NEXT: -- (Test14::B, 0) vtable address --
+// CHECK-NEXT: -- (Test14::C, 0) vtable address --
+// CHECK-NEXT: -- (Test14::D, 0) vtable address --
+// CHECK-NEXT: 4 | void Test14::D::f()
+struct D : C, virtual B {
+ virtual void f();
+};
+void D::f() { }
+
+}
+
+namespace Test15 {
+
+// Test that we don't emit an extra vtable for B since it's a primary base of C.
+struct A { virtual void a(); };
+struct B { virtual void b(); };
+
+struct C : virtual B { };
+
+// CHECK: Vtable for 'Test15::D' (11 entries).
+// CHECK-NEXT: 0 | vbase_offset (8)
+// CHECK-NEXT: 1 | vbase_offset (8)
+// CHECK-NEXT: 2 | offset_to_top (0)
+// CHECK-NEXT: 3 | Test15::D RTTI
+// CHECK-NEXT: -- (Test15::A, 0) vtable address --
+// CHECK-NEXT: -- (Test15::D, 0) vtable address --
+// CHECK-NEXT: 4 | void Test15::A::a()
+// CHECK-NEXT: 5 | void Test15::D::f()
+// CHECK-NEXT: 6 | vbase_offset (0)
+// CHECK-NEXT: 7 | vcall_offset (0)
+// CHECK-NEXT: 8 | offset_to_top (-8)
+// CHECK-NEXT: 9 | Test15::D RTTI
+// CHECK-NEXT: -- (Test15::B, 8) vtable address --
+// CHECK-NEXT: -- (Test15::C, 8) vtable address --
+// CHECK-NEXT: 10 | void Test15::B::b()
+struct D : A, virtual B, virtual C {
+ virtual void f();
+};
+void D::f() { }
+
+}
+
+namespace Test16 {
+
+// Test that destructors share vcall offsets.
+
+struct A { virtual ~A(); };
+struct B { virtual ~B(); };
+
+struct C : A, B { virtual ~C(); };
+
+// CHECK: Vtable for 'Test16::D' (15 entries).
+// CHECK-NEXT: 0 | vbase_offset (8)
+// CHECK-NEXT: 1 | offset_to_top (0)
+// CHECK-NEXT: 2 | Test16::D RTTI
+// CHECK-NEXT: -- (Test16::D, 0) vtable address --
+// CHECK-NEXT: 3 | void Test16::D::f()
+// CHECK-NEXT: 4 | Test16::D::~D() [complete]
+// CHECK-NEXT: 5 | Test16::D::~D() [deleting]
+// CHECK-NEXT: 6 | vcall_offset (-8)
+// CHECK-NEXT: 7 | offset_to_top (-8)
+// CHECK-NEXT: 8 | Test16::D RTTI
+// CHECK-NEXT: -- (Test16::A, 8) vtable address --
+// CHECK-NEXT: -- (Test16::C, 8) vtable address --
+// CHECK-NEXT: 9 | Test16::D::~D() [complete]
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT: 10 | Test16::D::~D() [deleting]
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT: 11 | offset_to_top (-16)
+// CHECK-NEXT: 12 | Test16::D RTTI
+// CHECK-NEXT: -- (Test16::B, 16) vtable address --
+// CHECK-NEXT: 13 | Test16::D::~D() [complete]
+// CHECK-NEXT: [this adjustment: -8 non-virtual, -24 vcall offset offset]
+// CHECK-NEXT: 14 | Test16::D::~D() [deleting]
+// CHECK-NEXT: [this adjustment: -8 non-virtual, -24 vcall offset offset]
+struct D : virtual C {
+ virtual void f();
+};
+void D::f() { }
+
+}
+
+namespace Test17 {
+
+// Test that we don't mark E::f in the C-in-E vtable as unused.
+struct A { virtual void f(); };
+struct B : virtual A { virtual void f(); };
+struct C : virtual A { virtual void f(); };
+struct D : virtual B, virtual C { virtual void f(); };
+
+// CHECK: Vtable for 'Test17::E' (13 entries).
+// CHECK-NEXT: 0 | vbase_offset (0)
+// CHECK-NEXT: 1 | vbase_offset (8)
+// CHECK-NEXT: 2 | vbase_offset (0)
+// CHECK-NEXT: 3 | vbase_offset (0)
+// CHECK-NEXT: 4 | vcall_offset (0)
+// CHECK-NEXT: 5 | offset_to_top (0)
+// CHECK-NEXT: 6 | Test17::E RTTI
+// CHECK-NEXT: -- (Test17::A, 0) vtable address --
+// CHECK-NEXT: -- (Test17::B, 0) vtable address --
+// CHECK-NEXT: -- (Test17::D, 0) vtable address --
+// CHECK-NEXT: -- (Test17::E, 0) vtable address --
+// CHECK-NEXT: 7 | void Test17::E::f()
+// CHECK-NEXT: 8 | vbase_offset (-8)
+// CHECK-NEXT: 9 | vcall_offset (-8)
+// CHECK-NEXT: 10 | offset_to_top (-8)
+// CHECK-NEXT: 11 | Test17::E RTTI
+// CHECK-NEXT: -- (Test17::A, 8) vtable address --
+// CHECK-NEXT: -- (Test17::C, 8) vtable address --
+// CHECK-NEXT: 12 | void Test17::E::f()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+class E : virtual D {
+ virtual void f();
+};
+void E::f() {}
+
+}
+
+namespace Test18 {
+
+// Test that we compute the right 'this' adjustment offsets.
+
+struct A {
+ virtual void f();
+ virtual void g();
+};
+
+struct B : virtual A {
+ virtual void f();
+};
+
+struct C : A, B {
+ virtual void g();
+};
+
+// CHECK: Vtable for 'Test18::D' (24 entries).
+// CHECK-NEXT: 0 | vbase_offset (8)
+// CHECK-NEXT: 1 | vbase_offset (0)
+// CHECK-NEXT: 2 | vbase_offset (0)
+// CHECK-NEXT: 3 | vcall_offset (8)
+// CHECK-NEXT: 4 | vcall_offset (0)
+// CHECK-NEXT: 5 | offset_to_top (0)
+// CHECK-NEXT: 6 | Test18::D RTTI
+// CHECK-NEXT: -- (Test18::A, 0) vtable address --
+// CHECK-NEXT: -- (Test18::B, 0) vtable address --
+// CHECK-NEXT: -- (Test18::D, 0) vtable address --
+// CHECK-NEXT: 7 | void Test18::D::f()
+// CHECK-NEXT: 8 | void Test18::C::g()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
+// CHECK-NEXT: 9 | void Test18::D::h()
+// CHECK-NEXT: 10 | vcall_offset (0)
+// CHECK-NEXT: 11 | vcall_offset (-8)
+// CHECK-NEXT: 12 | vbase_offset (-8)
+// CHECK-NEXT: 13 | offset_to_top (-8)
+// CHECK-NEXT: 14 | Test18::D RTTI
+// CHECK-NEXT: -- (Test18::A, 8) vtable address --
+// CHECK-NEXT: -- (Test18::C, 8) vtable address --
+// CHECK-NEXT: 15 | void Test18::D::f()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset]
+// CHECK-NEXT: 16 | void Test18::C::g()
+// CHECK-NEXT: 17 | vbase_offset (-16)
+// CHECK-NEXT: 18 | vcall_offset (-8)
+// CHECK-NEXT: 19 | vcall_offset (-16)
+// CHECK-NEXT: 20 | offset_to_top (-16)
+// CHECK-NEXT: 21 | Test18::D RTTI
+// CHECK-NEXT: -- (Test18::A, 16) vtable address --
+// CHECK-NEXT: -- (Test18::B, 16) vtable address --
+// CHECK-NEXT: 22 | void Test18::D::f()
+// CHECK-NEXT: [this adjustment: -8 non-virtual, -32 vcall offset offset]
+// CHECK-NEXT: 23 | [unused] void Test18::C::g()
+struct D : virtual B, virtual C, virtual A
+{
+ virtual void f();
+ virtual void h();
+};
+void D::f() {}
+
+}
+
+namespace Test19 {
+
+// Another 'this' adjustment test.
+
+struct A {
+ int a;
+
+ virtual void f();
+};
+
+struct B : A {
+ int b;
+
+ virtual void g();
+};
+
+struct C {
+ virtual void c();
+};
+
+// CHECK: Vtable for 'Test19::D' (13 entries).
+// CHECK-NEXT: 0 | vbase_offset (24)
+// CHECK-NEXT: 1 | offset_to_top (0)
+// CHECK-NEXT: 2 | Test19::D RTTI
+// CHECK-NEXT: -- (Test19::C, 0) vtable address --
+// CHECK-NEXT: -- (Test19::D, 0) vtable address --
+// CHECK-NEXT: 3 | void Test19::C::c()
+// CHECK-NEXT: 4 | void Test19::D::f()
+// CHECK-NEXT: 5 | offset_to_top (-8)
+// CHECK-NEXT: 6 | Test19::D RTTI
+// CHECK-NEXT: -- (Test19::A, 8) vtable address --
+// CHECK-NEXT: -- (Test19::B, 8) vtable address --
+// CHECK-NEXT: 7 | void Test19::D::f()
+// CHECK-NEXT: [this adjustment: -8 non-virtual]
+// CHECK-NEXT: 8 | void Test19::B::g()
+// CHECK-NEXT: 9 | vcall_offset (-24)
+// CHECK-NEXT: 10 | offset_to_top (-24)
+// CHECK-NEXT: 11 | Test19::D RTTI
+// CHECK-NEXT: -- (Test19::A, 24) vtable address --
+// CHECK-NEXT: 12 | void Test19::D::f()
+// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset]
+struct D : C, B, virtual A {
+ virtual void f();
+};
+void D::f() { }
+
+}
+
+namespace Test20 {
+
+// pure virtual member functions should never have 'this' adjustments.
+
+struct A {
+ virtual void f() = 0;
+ virtual void g();
+};
+
+struct B : A { };
+
+// CHECK: Vtable for 'Test20::C' (9 entries).
+// CHECK-NEXT: 0 | offset_to_top (0)
+// CHECK-NEXT: 1 | Test20::C RTTI
+// CHECK-NEXT: -- (Test20::A, 0) vtable address --
+// CHECK-NEXT: -- (Test20::C, 0) vtable address --
+// CHECK-NEXT: 2 | void Test20::C::f() [pure]
+// CHECK-NEXT: 3 | void Test20::A::g()
+// CHECK-NEXT: 4 | void Test20::C::h()
+// CHECK-NEXT: 5 | offset_to_top (-8)
+// CHECK-NEXT: 6 | Test20::C RTTI
+// CHECK-NEXT: -- (Test20::A, 8) vtable address --
+// CHECK-NEXT: -- (Test20::B, 8) vtable address --
+// CHECK-NEXT: 7 | void Test20::C::f() [pure]
+// CHECK-NEXT: 8 | void Test20::A::g()
+struct C : A, B {
+ virtual void f() = 0;
+ virtual void h();
+};
+void C::h() { }
+
+}
+
+namespace Test21 {
+
+// Test that we get vbase offsets right in secondary vtables.
+struct A {
+ virtual void f();
+};
+
+struct B : virtual A { };
+class C : virtual B { };
+class D : virtual C { };
+
+class E : virtual C { };
+
+// CHECK: Vtable for 'Test21::F' (16 entries).
+// CHECK-NEXT: 0 | vbase_offset (8)
+// CHECK-NEXT: 1 | vbase_offset (0)
+// CHECK-NEXT: 2 | vbase_offset (0)
+// CHECK-NEXT: 3 | vbase_offset (0)
+// CHECK-NEXT: 4 | vbase_offset (0)
+// CHECK-NEXT: 5 | vcall_offset (0)
+// CHECK-NEXT: 6 | offset_to_top (0)
+// CHECK-NEXT: 7 | Test21::F RTTI
+// CHECK-NEXT: -- (Test21::A, 0) vtable address --
+// CHECK-NEXT: -- (Test21::B, 0) vtable address --
+// CHECK-NEXT: -- (Test21::C, 0) vtable address --
+// CHECK-NEXT: -- (Test21::D, 0) vtable address --
+// CHECK-NEXT: -- (Test21::F, 0) vtable address --
+// CHECK-NEXT: 8 | void Test21::F::f()
+// CHECK-NEXT: 9 | vbase_offset (-8)
+// CHECK-NEXT: 10 | vbase_offset (-8)
+// CHECK-NEXT: 11 | vbase_offset (-8)
+// CHECK-NEXT: 12 | vcall_offset (-8)
+// CHECK-NEXT: 13 | offset_to_top (-8)
+// CHECK-NEXT: 14 | Test21::F RTTI
+// CHECK-NEXT: -- (Test21::A, 8) vtable address --
+// CHECK-NEXT: -- (Test21::B, 8) vtable address --
+// CHECK-NEXT: -- (Test21::C, 8) vtable address --
+// CHECK-NEXT: -- (Test21::E, 8) vtable address --
+// CHECK-NEXT: 15 | [unused] void Test21::F::f()
+class F : virtual D, virtual E {
+ virtual void f();
+};
+void F::f() { }
+
+}
+
+namespace Test22 {
+
+// Very simple construction vtable test.
+struct V1 {
+ int v1;
+};
+
+struct V2 : virtual V1 {
+ int v2;
+};
+
+// CHECK: Vtable for 'Test22::C' (8 entries).
+// CHECK-NEXT: 0 | vbase_offset (16)
+// CHECK-NEXT: 1 | vbase_offset (12)
+// CHECK-NEXT: 2 | offset_to_top (0)
+// CHECK-NEXT: 3 | Test22::C RTTI
+// CHECK-NEXT: -- (Test22::C, 0) vtable address --
+// CHECK-NEXT: 4 | void Test22::C::f()
+// CHECK-NEXT: 5 | vbase_offset (-4)
+// CHECK-NEXT: 6 | offset_to_top (-16)
+// CHECK-NEXT: 7 | Test22::C RTTI
+// CHECK-NEXT: -- (Test22::V2, 16) vtable address --
+
+// CHECK: Construction vtable for ('Test22::V2', 16) in 'Test22::C' (3 entries).
+// CHECK-NEXT: 0 | vbase_offset (-4)
+// CHECK-NEXT: 1 | offset_to_top (0)
+// CHECK-NEXT: 2 | Test22::V2 RTTI
+
+struct C : virtual V1, virtual V2 {
+ int c;
+ virtual void f();
+};
+void C::f() { }
+
+}
+
+namespace Test23 {
+
+struct A {
+ int a;
+};
+
+struct B : virtual A {
+ int b;
+};
+
+struct C : A, virtual B {
+ int c;
+};
+
+// CHECK: Vtable for 'Test23::D' (7 entries).
+// CHECK-NEXT: 0 | vbase_offset (20)
+// CHECK-NEXT: 1 | vbase_offset (24)
+// CHECK-NEXT: 2 | offset_to_top (0)
+// CHECK-NEXT: 3 | Test23::D RTTI
+// CHECK-NEXT: -- (Test23::C, 0) vtable address --
+// CHECK-NEXT: -- (Test23::D, 0) vtable address --
+// CHECK-NEXT: 4 | vbase_offset (-4)
+// CHECK-NEXT: 5 | offset_to_top (-24)
+// CHECK-NEXT: 6 | Test23::D RTTI
+// CHECK-NEXT: -- (Test23::B, 24) vtable address --
+
+// CHECK: Construction vtable for ('Test23::C', 0) in 'Test23::D' (7 entries).
+// CHECK-NEXT: 0 | vbase_offset (20)
+// CHECK-NEXT: 1 | vbase_offset (24)
+// CHECK-NEXT: 2 | offset_to_top (0)
+// CHECK-NEXT: 3 | Test23::C RTTI
+// CHECK-NEXT: -- (Test23::C, 0) vtable address --
+// CHECK-NEXT: 4 | vbase_offset (-4)
+// CHECK-NEXT: 5 | offset_to_top (-24)
+// CHECK-NEXT: 6 | Test23::C RTTI
+// CHECK-NEXT: -- (Test23::B, 24) vtable address --
+
+// CHECK: Construction vtable for ('Test23::B', 24) in 'Test23::D' (3 entries).
+// CHECK-NEXT: 0 | vbase_offset (-4)
+// CHECK-NEXT: 1 | offset_to_top (0)
+// CHECK-NEXT: 2 | Test23::B RTTI
+// CHECK-NEXT: -- (Test23::B, 24) vtable address --
+
+struct D : virtual A, virtual B, C {
+ int d;
+
+ void f();
+};
+void D::f() { }
+
+}
+
+namespace Test24 {
+
+// Another construction vtable test.
+
+struct A {
+ virtual void f();
+};
+
+struct B : virtual A { };
+struct C : virtual A { };
+
+// CHECK: Vtable for 'Test24::D' (10 entries).
+// CHECK-NEXT: 0 | vbase_offset (0)
+// CHECK-NEXT: 1 | vcall_offset (0)
+// CHECK-NEXT: 2 | offset_to_top (0)
+// CHECK-NEXT: 3 | Test24::D RTTI
+// CHECK-NEXT: -- (Test24::A, 0) vtable address --
+// CHECK-NEXT: -- (Test24::B, 0) vtable address --
+// CHECK-NEXT: -- (Test24::D, 0) vtable address --
+// CHECK-NEXT: 4 | void Test24::D::f()
+// CHECK-NEXT: 5 | vbase_offset (-8)
+// CHECK-NEXT: 6 | vcall_offset (-8)
+// CHECK-NEXT: 7 | offset_to_top (-8)
+// CHECK-NEXT: 8 | Test24::D RTTI
+// CHECK-NEXT: -- (Test24::A, 8) vtable address --
+// CHECK-NEXT: -- (Test24::C, 8) vtable address --
+// CHECK-NEXT: 9 | [unused] void Test24::D::f()
+
+// CHECK: Construction vtable for ('Test24::B', 0) in 'Test24::D' (5 entries).
+// CHECK-NEXT: 0 | vbase_offset (0)
+// CHECK-NEXT: 1 | vcall_offset (0)
+// CHECK-NEXT: 2 | offset_to_top (0)
+// CHECK-NEXT: 3 | Test24::B RTTI
+// CHECK-NEXT: -- (Test24::A, 0) vtable address --
+// CHECK-NEXT: -- (Test24::B, 0) vtable address --
+// CHECK-NEXT: 4 | void Test24::A::f()
+
+// CHECK: Construction vtable for ('Test24::C', 8) in 'Test24::D' (9 entries).
+// CHECK-NEXT: 0 | vbase_offset (-8)
+// CHECK-NEXT: 1 | vcall_offset (-8)
+// CHECK-NEXT: 2 | offset_to_top (0)
+// CHECK-NEXT: 3 | Test24::C RTTI
+// CHECK-NEXT: -- (Test24::A, 8) vtable address --
+// CHECK-NEXT: -- (Test24::C, 8) vtable address --
+// CHECK-NEXT: 4 | [unused] void Test24::A::f()
+// CHECK-NEXT: 5 | vcall_offset (0)
+// CHECK-NEXT: 6 | offset_to_top (8)
+// CHECK-NEXT: 7 | Test24::C RTTI
+// CHECK-NEXT: -- (Test24::A, 0) vtable address --
+// CHECK-NEXT: 8 | void Test24::A::f()
+struct D : B, C {
+ virtual void f();
+};
+void D::f() { }
+
+}
+
+namespace Test25 {
+
+// This mainly tests that we don't assert on this class hierarchy.
+
+struct V {
+ virtual void f();
+};
+
+struct A : virtual V { };
+struct B : virtual V { };
+
+// CHECK: Vtable for 'Test25::C' (11 entries).
+// CHECK-NEXT: 0 | vbase_offset (0)
+// CHECK-NEXT: 1 | vcall_offset (0)
+// CHECK-NEXT: 2 | offset_to_top (0)
+// CHECK-NEXT: 3 | Test25::C RTTI
+// CHECK-NEXT: -- (Test25::A, 0) vtable address --
+// CHECK-NEXT: -- (Test25::C, 0) vtable address --
+// CHECK-NEXT: -- (Test25::V, 0) vtable address --
+// CHECK-NEXT: 4 | void Test25::V::f()
+// CHECK-NEXT: 5 | void Test25::C::g()
+// CHECK-NEXT: 6 | vbase_offset (-8)
+// CHECK-NEXT: 7 | vcall_offset (-8)
+// CHECK-NEXT: 8 | offset_to_top (-8)
+// CHECK-NEXT: 9 | Test25::C RTTI
+// CHECK-NEXT: -- (Test25::B, 8) vtable address --
+// CHECK-NEXT: -- (Test25::V, 8) vtable address --
+// CHECK-NEXT: 10 | [unused] void Test25::V::f()
+
+// CHECK: Construction vtable for ('Test25::A', 0) in 'Test25::C' (5 entries).
+// CHECK-NEXT: 0 | vbase_offset (0)
+// CHECK-NEXT: 1 | vcall_offset (0)
+// CHECK-NEXT: 2 | offset_to_top (0)
+// CHECK-NEXT: 3 | Test25::A RTTI
+// CHECK-NEXT: -- (Test25::A, 0) vtable address --
+// CHECK-NEXT: -- (Test25::V, 0) vtable address --
+// CHECK-NEXT: 4 | void Test25::V::f()
+
+// CHECK: Construction vtable for ('Test25::B', 8) in 'Test25::C' (9 entries).
+// CHECK-NEXT: 0 | vbase_offset (-8)
+// CHECK-NEXT: 1 | vcall_offset (-8)
+// CHECK-NEXT: 2 | offset_to_top (0)
+// CHECK-NEXT: 3 | Test25::B RTTI
+// CHECK-NEXT: -- (Test25::B, 8) vtable address --
+// CHECK-NEXT: -- (Test25::V, 8) vtable address --
+// CHECK-NEXT: 4 | [unused] void Test25::V::f()
+// CHECK-NEXT: 5 | vcall_offset (0)
+// CHECK-NEXT: 6 | offset_to_top (8)
+// CHECK-NEXT: 7 | Test25::B RTTI
+// CHECK-NEXT: -- (Test25::V, 0) vtable address --
+// CHECK-NEXT: 8 | void Test25::V::f()
+struct C : A, virtual V, B {
+ virtual void g();
+};
+void C::g() { }
+
+}
diff --git a/test/CodeGenCXX/vtable-pointer-initialization.cpp b/test/CodeGenCXX/vtable-pointer-initialization.cpp
index 92e0117..75620ab 100644
--- a/test/CodeGenCXX/vtable-pointer-initialization.cpp
+++ b/test/CodeGenCXX/vtable-pointer-initialization.cpp
@@ -19,14 +19,14 @@ struct A : Base {
Field field;
};
-// CHECK: define void @_ZN1AC1Ev(
+// CHECK: define void @_ZN1AC2Ev(
// CHECK: call void @_ZN4BaseC2Ev(
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2)
// CHECK: call void @_ZN5FieldC1Ev(
// CHECK: ret void
A::A() { }
-// CHECK: define void @_ZN1AD1Ev(
+// CHECK: define void @_ZN1AD2Ev(
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2)
// CHECK: call void @_ZN5FieldD1Ev(
// CHECK: call void @_ZN4BaseD2Ev(
@@ -42,13 +42,16 @@ struct B : Base {
void f() { B b; }
// CHECK: define linkonce_odr void @_ZN1BC1Ev(
-// CHECK: call void @_ZN4BaseC2Ev(
-// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2)
-// CHECK: call void @_ZN5FieldC1Ev
-// CHECK: ret void
+// CHECK: call void @_ZN1BC2Ev(
// CHECK: define linkonce_odr void @_ZN1BD1Ev(
// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2)
// CHECK: call void @_ZN5FieldD1Ev(
// CHECK: call void @_ZN4BaseD2Ev(
// CHECK: ret void
+
+// CHECK: define linkonce_odr void @_ZN1BC2Ev(
+// CHECK: call void @_ZN4BaseC2Ev(
+// CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2)
+// CHECK: call void @_ZN5FieldC1Ev
+// CHECK: ret void
diff --git a/test/CodeGenObjC/messages-2.m b/test/CodeGenObjC/messages-2.m
index 2a6e3dc..05e30ab 100644
--- a/test/CodeGenObjC/messages-2.m
+++ b/test/CodeGenObjC/messages-2.m
@@ -136,4 +136,7 @@ typedef struct {
x.height *= 2;
return x;
}
+-(const float) returnAConstFloat {
+ return 5;
+}
@end
diff --git a/test/CodeGenObjC/stand-alone-implementation.m b/test/CodeGenObjC/stand-alone-implementation.m
new file mode 100644
index 0000000..a519495
--- /dev/null
+++ b/test/CodeGenObjC/stand-alone-implementation.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fobjc-nonfragile-abi -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-X86-64 %s
+
+// radar 7547942
+// Allow injection of ivars into implementation's implicit class.
+
+@implementation INTFSTANDALONE // expected-warning {{cannot find interface declaration for 'INTFSTANDALONE'}}
+{
+ id IVAR1;
+ id IVAR2;
+}
+- (id) Meth { return IVAR1; }
+@end
+
+// CHECK-X86-64: @"OBJC_IVAR_$_INTFSTANDALONE.IVAR1"
+// CHECK-X86-64: @"OBJC_IVAR_$_INTFSTANDALONE.IVAR2"
+
diff --git a/test/Driver/clang-c-as-cxx.c b/test/Driver/clang-c-as-cxx.c
new file mode 100644
index 0000000..0e28178
--- /dev/null
+++ b/test/Driver/clang-c-as-cxx.c
@@ -0,0 +1,6 @@
+// RUN: %clangxx -### %s 2>&1 | FileCheck %s
+//
+// PR5803
+//
+// CHECK: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated
+// CHECK: "-cc1" {{.*}} "-x" "c++"
diff --git a/test/Index/Inputs/cindex-from-source.h b/test/Index/Inputs/cindex-from-source.h
new file mode 100644
index 0000000..d13d397
--- /dev/null
+++ b/test/Index/Inputs/cindex-from-source.h
@@ -0,0 +1 @@
+typedef int t0;
diff --git a/test/Index/annotate-tokens.c b/test/Index/annotate-tokens.c
index ef0069c..7fbf9cc 100644
--- a/test/Index/annotate-tokens.c
+++ b/test/Index/annotate-tokens.c
@@ -61,4 +61,5 @@ void f(void *ptr) {
// CHECK: Literal: ""Hello"" [9:24 - 9:31]
// CHECK: Punctuation: ";" [9:31 - 9:32]
// CHECK: Punctuation: "}" [10:1 - 10:2]
-
+// RUN: c-index-test -test-annotate-tokens=%s:4:1:165:32 %s | FileCheck %s
+// RUN: c-index-test -test-annotate-tokens=%s:4:1:165:38 %s | FileCheck %s
diff --git a/test/Index/c-index-api-loadTU-test.m b/test/Index/c-index-api-loadTU-test.m
index cd0c868..5b2f86e 100644
--- a/test/Index/c-index-api-loadTU-test.m
+++ b/test/Index/c-index-api-loadTU-test.m
@@ -3,8 +3,9 @@
@interface Foo
{
+ __attribute__((iboutlet)) id myoutlet;
}
-
+- (void) __attribute__((ibaction)) myMessage:(id)msg;
- foo;
+ fooC;
@@ -53,79 +54,71 @@ int main (int argc, const char * argv[]) {
main(someEnum, (const char **)bee);
}
-// CHECK: <invalid loc>:0:0: TypedefDecl=__int128_t:0:0 (Definition)
-// CHECK: <invalid loc>:0:0: TypedefDecl=__uint128_t:0:0 (Definition)
-// CHECK: <invalid loc>:0:0: TypedefDecl=SEL:0:0 (Definition)
-// CHECK: <invalid loc>:0:0: TypeRef=SEL:0:0
-// CHECK: <invalid loc>:0:0: TypedefDecl=id:0:0 (Definition)
-// CHECK: <invalid loc>:0:0: TypedefDecl=Class:0:0 (Definition)
-// CHECK: <invalid loc>:87:16: StructDecl=__va_list_tag:87:16 (Definition)
-// CHECK: <invalid loc>:87:42: FieldDecl=gp_offset:87:42 (Definition)
-// CHECK: <invalid loc>:87:63: FieldDecl=fp_offset:87:63 (Definition)
-// CHECK: <invalid loc>:87:81: FieldDecl=overflow_arg_area:87:81 (Definition)
-// CHECK: <invalid loc>:87:107: FieldDecl=reg_save_area:87:107 (Definition)
-// CHECK: <invalid loc>:87:123: TypedefDecl=__va_list_tag:87:123 (Definition)
-// CHECK: <invalid loc>:87:16: TypeRef=struct __va_list_tag:87:16
-// CHECK: <invalid loc>:87:159: TypedefDecl=__builtin_va_list:87:159 (Definition)
-// CHECK: <invalid loc>:87:145: TypeRef=__va_list_tag:87:123
-// CHECK: <invalid loc>:87:177: UnexposedExpr=
-// CHECK: c-index-api-loadTU-test.m:4:12: ObjCInterfaceDecl=Foo:4:12 Extent=[4:1 - 11:5]
-// CHECK: c-index-api-loadTU-test.m:8:1: ObjCInstanceMethodDecl=foo:8:1 Extent=[8:1 - 8:7]
-// CHECK: c-index-api-loadTU-test.m:9:1: ObjCClassMethodDecl=fooC:9:1 Extent=[9:1 - 9:8]
-// CHECK: c-index-api-loadTU-test.m:13:12: ObjCInterfaceDecl=Bar:13:12 Extent=[13:1 - 17:5]
-// CHECK: c-index-api-loadTU-test.m:13:18: ObjCSuperClassRef=Foo:4:12 Extent=[13:18 - 13:21]
-// CHECK: c-index-api-loadTU-test.m:19:12: ObjCCategoryDecl=FooCat:19:12 Extent=[19:1 - 22:5]
-// CHECK: c-index-api-loadTU-test.m:19:12: ObjCClassRef=Foo:4:12 Extent=[19:12 - 19:15]
-// CHECK: c-index-api-loadTU-test.m:20:1: ObjCInstanceMethodDecl=catMethodWithFloat::20:1 Extent=[20:1 - 20:41]
-// CHECK: c-index-api-loadTU-test.m:20:36: ParmDecl=fArg:20:36 (Definition) Extent=[20:29 - 20:40]
-// CHECK: c-index-api-loadTU-test.m:21:1: ObjCInstanceMethodDecl=floatMethod:21:1 Extent=[21:1 - 21:23]
-// CHECK: c-index-api-loadTU-test.m:24:1: ObjCProtocolDecl=Proto:24:1 (Definition) Extent=[24:1 - 26:5]
-// CHECK: c-index-api-loadTU-test.m:25:1: ObjCInstanceMethodDecl=pMethod:25:1 Extent=[25:1 - 25:11]
-// CHECK: c-index-api-loadTU-test.m:28:1: ObjCProtocolDecl=SubP:28:1 (Definition) Extent=[28:1 - 30:5]
-// CHECK: c-index-api-loadTU-test.m:28:17: ObjCProtocolRef=Proto:24:1 Extent=[28:17 - 28:22]
-// CHECK: c-index-api-loadTU-test.m:29:1: ObjCInstanceMethodDecl=spMethod:29:1 Extent=[29:1 - 29:12]
-// CHECK: c-index-api-loadTU-test.m:32:12: ObjCInterfaceDecl=Baz:32:12 Extent=[32:1 - 39:5]
-// CHECK: c-index-api-loadTU-test.m:32:18: ObjCSuperClassRef=Bar:13:12 Extent=[32:18 - 32:21]
-// CHECK: c-index-api-loadTU-test.m:32:23: ObjCProtocolRef=SubP:28:1 Extent=[32:23 - 32:27]
-// CHECK: c-index-api-loadTU-test.m:34:9: ObjCIvarDecl=_anIVar:34:9 (Definition) Extent=[34:9 - 34:16]
-// CHECK: c-index-api-loadTU-test.m:37:1: ObjCInstanceMethodDecl=bazMethod:37:1 Extent=[37:1 - 37:21]
-// CHECK: c-index-api-loadTU-test.m:41:1: EnumDecl=:41:1 (Definition) Extent=[41:1 - 43:2]
-// CHECK: c-index-api-loadTU-test.m:42:3: EnumConstantDecl=someEnum:42:3 (Definition) Extent=[42:3 - 42:11]
-// CHECK: c-index-api-loadTU-test.m:45:5: FunctionDecl=main:45:5 (Definition) Extent=[45:5 - 54:2]
-// CHECK: c-index-api-loadTU-test.m:45:15: ParmDecl=argc:45:15 (Definition) Extent=[45:11 - 45:19]
-// CHECK: c-index-api-loadTU-test.m:45:34: ParmDecl=argv:45:34 (Definition) Extent=[45:27 - 45:38]
-// CHECK: c-index-api-loadTU-test.m:45:5: UnexposedStmt= Extent=[45:42 - 54:2]
-// CHECK: c-index-api-loadTU-test.m:45:5: UnexposedStmt= Extent=[46:2 - 46:12]
-// CHECK: c-index-api-loadTU-test.m:46:8: VarDecl=bee:46:8 (Definition) Extent=[46:2 - 46:11]
-// CHECK: c-index-api-loadTU-test.m:46:2: ObjCClassRef=Baz:32:12 Extent=[46:2 - 46:5]
-// CHECK: c-index-api-loadTU-test.m:46:8: UnexposedStmt= Extent=[47:2 - 47:19]
-// CHECK: c-index-api-loadTU-test.m:47:5: VarDecl=a:47:5 (Definition) Extent=[47:2 - 47:18]
-// CHECK: c-index-api-loadTU-test.m:47:2: TypeRef=id:0:0 Extent=[47:2 - 47:4]
-// CHECK: c-index-api-loadTU-test.m:47:9: ObjCMessageExpr=foo:8:1 Extent=[47:9 - 47:18]
-// CHECK: c-index-api-loadTU-test.m:47:10: DeclRefExpr=bee:46:8 Extent=[47:10 - 47:13]
-// CHECK: c-index-api-loadTU-test.m:47:5: UnexposedStmt= Extent=[48:2 - 48:27]
-// CHECK: c-index-api-loadTU-test.m:48:12: VarDecl=c:48:12 (Definition) Extent=[48:2 - 48:26]
+// CHECK: c-index-api-loadTU-test.m:4:12: ObjCInterfaceDecl=Foo:4:12 Extent=[4:1 - 12:5]
+// CHECK: c-index-api-loadTU-test.m:6:32: ObjCIvarDecl=myoutlet:6:32 (Definition) Extent=[6:32 - 6:40]
+// CHECK: c-index-api-loadTU-test.m:6:32: attribute(iboutlet)= Extent=[6:32 - 6:40]
+// CHECK: c-index-api-loadTU-test.m:6:29: TypeRef=id:0:0 Extent=[6:29 - 6:31]
+// CHECK: c-index-api-loadTU-test.m:8:1: ObjCInstanceMethodDecl=myMessage::8:1 Extent=[8:1 - 8:54]
+// CHECK: c-index-api-loadTU-test.m:8:1: attribute(ibaction)= Extent=[8:1 - 8:54]
+// CHECK: c-index-api-loadTU-test.m:8:50: ParmDecl=msg:8:50 (Definition) Extent=[8:47 - 8:53]
+// CHECK: c-index-api-loadTU-test.m:8:47: TypeRef=id:0:0 Extent=[8:47 - 8:49]
+// CHECK: c-index-api-loadTU-test.m:9:1: ObjCInstanceMethodDecl=foo:9:1 Extent=[9:1 - 9:7]
+// CHECK: c-index-api-loadTU-test.m:10:1: ObjCClassMethodDecl=fooC:10:1 Extent=[10:1 - 10:8]
+// CHECK: c-index-api-loadTU-test.m:14:12: ObjCInterfaceDecl=Bar:14:12 Extent=[14:1 - 18:5]
+// CHECK: c-index-api-loadTU-test.m:14:18: ObjCSuperClassRef=Foo:4:12 Extent=[14:18 - 14:21]
+// CHECK: c-index-api-loadTU-test.m:20:12: ObjCCategoryDecl=FooCat:20:12 Extent=[20:1 - 23:5]
+// CHECK: c-index-api-loadTU-test.m:20:12: ObjCClassRef=Foo:4:12 Extent=[20:12 - 20:15]
+// CHECK: c-index-api-loadTU-test.m:21:1: ObjCInstanceMethodDecl=catMethodWithFloat::21:1 Extent=[21:1 - 21:41]
+// CHECK: c-index-api-loadTU-test.m:21:36: ParmDecl=fArg:21:36 (Definition) Extent=[21:29 - 21:40]
+// CHECK: c-index-api-loadTU-test.m:22:1: ObjCInstanceMethodDecl=floatMethod:22:1 Extent=[22:1 - 22:23]
+// CHECK: c-index-api-loadTU-test.m:25:1: ObjCProtocolDecl=Proto:25:1 (Definition) Extent=[25:1 - 27:5]
+// CHECK: c-index-api-loadTU-test.m:26:1: ObjCInstanceMethodDecl=pMethod:26:1 Extent=[26:1 - 26:11]
+// CHECK: c-index-api-loadTU-test.m:29:1: ObjCProtocolDecl=SubP:29:1 (Definition) Extent=[29:1 - 31:5]
+// CHECK: c-index-api-loadTU-test.m:29:17: ObjCProtocolRef=Proto:25:1 Extent=[29:17 - 29:22]
+// CHECK: c-index-api-loadTU-test.m:30:1: ObjCInstanceMethodDecl=spMethod:30:1 Extent=[30:1 - 30:12]
+// CHECK: c-index-api-loadTU-test.m:33:12: ObjCInterfaceDecl=Baz:33:12 Extent=[33:1 - 40:5]
+// CHECK: c-index-api-loadTU-test.m:33:18: ObjCSuperClassRef=Bar:14:12 Extent=[33:18 - 33:21]
+// CHECK: c-index-api-loadTU-test.m:33:23: ObjCProtocolRef=SubP:29:1 Extent=[33:23 - 33:27]
+// CHECK: c-index-api-loadTU-test.m:35:9: ObjCIvarDecl=_anIVar:35:9 (Definition) Extent=[35:9 - 35:16]
+// CHECK: c-index-api-loadTU-test.m:38:1: ObjCInstanceMethodDecl=bazMethod:38:1 Extent=[38:1 - 38:21]
+// CHECK: c-index-api-loadTU-test.m:42:1: EnumDecl=:42:1 (Definition) Extent=[42:1 - 44:2]
+// CHECK: c-index-api-loadTU-test.m:43:3: EnumConstantDecl=someEnum:43:3 (Definition) Extent=[43:3 - 43:11]
+// CHECK: c-index-api-loadTU-test.m:46:5: FunctionDecl=main:46:5 (Definition) Extent=[46:5 - 55:2]
+// CHECK: c-index-api-loadTU-test.m:46:15: ParmDecl=argc:46:15 (Definition) Extent=[46:11 - 46:19]
+// CHECK: c-index-api-loadTU-test.m:46:34: ParmDecl=argv:46:34 (Definition) Extent=[46:27 - 46:38]
+// CHECK: c-index-api-loadTU-test.m:46:5: UnexposedStmt= Extent=[46:42 - 55:2]
+// CHECK: c-index-api-loadTU-test.m:46:5: UnexposedStmt= Extent=[47:2 - 47:12]
+// CHECK: c-index-api-loadTU-test.m:47:8: VarDecl=bee:47:8 (Definition) Extent=[47:2 - 47:11]
+// CHECK: c-index-api-loadTU-test.m:47:2: ObjCClassRef=Baz:33:12 Extent=[47:2 - 47:5]
+// CHECK: c-index-api-loadTU-test.m:47:8: UnexposedStmt= Extent=[48:2 - 48:19]
+// CHECK: c-index-api-loadTU-test.m:48:5: VarDecl=a:48:5 (Definition) Extent=[48:2 - 48:18]
// CHECK: c-index-api-loadTU-test.m:48:2: TypeRef=id:0:0 Extent=[48:2 - 48:4]
-// CHECK: c-index-api-loadTU-test.m:48:6: ObjCProtocolRef=SubP:28:1 Extent=[48:6 - 48:10]
-// CHECK: c-index-api-loadTU-test.m:48:16: UnexposedExpr=fooC:9:1 Extent=[48:16 - 48:26]
-// CHECK: c-index-api-loadTU-test.m:48:16: ObjCMessageExpr=fooC:9:1 Extent=[48:16 - 48:26]
-// CHECK: c-index-api-loadTU-test.m:48:12: UnexposedStmt= Extent=[49:2 - 49:15]
-// CHECK: c-index-api-loadTU-test.m:49:13: VarDecl=d:49:13 (Definition) Extent=[49:2 - 49:14]
+// CHECK: c-index-api-loadTU-test.m:48:9: ObjCMessageExpr=foo:9:1 Extent=[48:9 - 48:18]
+// CHECK: c-index-api-loadTU-test.m:48:10: DeclRefExpr=bee:47:8 Extent=[48:10 - 48:13]
+// CHECK: c-index-api-loadTU-test.m:48:5: UnexposedStmt= Extent=[49:2 - 49:27]
+// CHECK: c-index-api-loadTU-test.m:49:12: VarDecl=c:49:12 (Definition) Extent=[49:2 - 49:26]
// CHECK: c-index-api-loadTU-test.m:49:2: TypeRef=id:0:0 Extent=[49:2 - 49:4]
-// CHECK: c-index-api-loadTU-test.m:49:6: ObjCProtocolRef=Proto:24:1 Extent=[49:6 - 49:11]
-// CHECK: c-index-api-loadTU-test.m:50:2: UnexposedExpr= Extent=[50:2 - 50:7]
-// CHECK: c-index-api-loadTU-test.m:50:2: DeclRefExpr=d:49:13 Extent=[50:2 - 50:3]
-// CHECK: c-index-api-loadTU-test.m:50:6: UnexposedExpr=c:48:12 Extent=[50:6 - 50:7]
-// CHECK: c-index-api-loadTU-test.m:50:6: DeclRefExpr=c:48:12 Extent=[50:6 - 50:7]
-// CHECK: c-index-api-loadTU-test.m:51:2: ObjCMessageExpr=pMethod:25:1 Extent=[51:2 - 51:13]
-// CHECK: c-index-api-loadTU-test.m:51:3: DeclRefExpr=d:49:13 Extent=[51:3 - 51:4]
-// CHECK: c-index-api-loadTU-test.m:52:2: ObjCMessageExpr=catMethodWithFloat::20:1 Extent=[52:2 - 52:44]
-// CHECK: c-index-api-loadTU-test.m:52:3: DeclRefExpr=bee:46:8 Extent=[52:3 - 52:6]
-// CHECK: c-index-api-loadTU-test.m:52:26: ObjCMessageExpr=floatMethod:21:1 Extent=[52:26 - 52:43]
-// CHECK: c-index-api-loadTU-test.m:52:27: DeclRefExpr=bee:46:8 Extent=[52:27 - 52:30]
-// CHECK: c-index-api-loadTU-test.m:53:3: CallExpr=main:45:5 Extent=[53:3 - 53:37]
-// CHECK: c-index-api-loadTU-test.m:53:3: UnexposedExpr=main:45:5 Extent=[53:3 - 53:7]
-// CHECK: c-index-api-loadTU-test.m:53:3: DeclRefExpr=main:45:5 Extent=[53:3 - 53:7]
-// CHECK: c-index-api-loadTU-test.m:53:8: DeclRefExpr=someEnum:42:3 Extent=[53:8 - 53:16]
-// CHECK: c-index-api-loadTU-test.m:53:18: UnexposedExpr=bee:46:8 Extent=[53:18 - 53:36]
-// CHECK: c-index-api-loadTU-test.m:53:33: DeclRefExpr=bee:46:8 Extent=[53:33 - 53:36]
+// CHECK: c-index-api-loadTU-test.m:49:6: ObjCProtocolRef=SubP:29:1 Extent=[49:6 - 49:10]
+// CHECK: c-index-api-loadTU-test.m:49:16: UnexposedExpr=fooC:10:1 Extent=[49:16 - 49:26]
+// CHECK: c-index-api-loadTU-test.m:49:16: ObjCMessageExpr=fooC:10:1 Extent=[49:16 - 49:26]
+// CHECK: c-index-api-loadTU-test.m:49:12: UnexposedStmt= Extent=[50:2 - 50:15]
+// CHECK: c-index-api-loadTU-test.m:50:13: VarDecl=d:50:13 (Definition) Extent=[50:2 - 50:14]
+// CHECK: c-index-api-loadTU-test.m:50:2: TypeRef=id:0:0 Extent=[50:2 - 50:4]
+// CHECK: c-index-api-loadTU-test.m:50:6: ObjCProtocolRef=Proto:25:1 Extent=[50:6 - 50:11]
+// CHECK: c-index-api-loadTU-test.m:51:2: UnexposedExpr= Extent=[51:2 - 51:7]
+// CHECK: c-index-api-loadTU-test.m:51:2: DeclRefExpr=d:50:13 Extent=[51:2 - 51:3]
+// CHECK: c-index-api-loadTU-test.m:51:6: UnexposedExpr=c:49:12 Extent=[51:6 - 51:7]
+// CHECK: c-index-api-loadTU-test.m:51:6: DeclRefExpr=c:49:12 Extent=[51:6 - 51:7]
+// CHECK: c-index-api-loadTU-test.m:52:2: ObjCMessageExpr=pMethod:26:1 Extent=[52:2 - 52:13]
+// CHECK: c-index-api-loadTU-test.m:52:3: DeclRefExpr=d:50:13 Extent=[52:3 - 52:4]
+// CHECK: c-index-api-loadTU-test.m:53:2: ObjCMessageExpr=catMethodWithFloat::21:1 Extent=[53:2 - 53:44]
+// CHECK: c-index-api-loadTU-test.m:53:3: DeclRefExpr=bee:47:8 Extent=[53:3 - 53:6]
+// CHECK: c-index-api-loadTU-test.m:53:26: ObjCMessageExpr=floatMethod:22:1 Extent=[53:26 - 53:43]
+// CHECK: c-index-api-loadTU-test.m:53:27: DeclRefExpr=bee:47:8 Extent=[53:27 - 53:30]
+// CHECK: c-index-api-loadTU-test.m:54:3: CallExpr=main:46:5 Extent=[54:3 - 54:37]
+// CHECK: c-index-api-loadTU-test.m:54:3: UnexposedExpr=main:46:5 Extent=[54:3 - 54:7]
+// CHECK: c-index-api-loadTU-test.m:54:3: DeclRefExpr=main:46:5 Extent=[54:3 - 54:7]
+// CHECK: c-index-api-loadTU-test.m:54:8: DeclRefExpr=someEnum:43:3 Extent=[54:8 - 54:16]
+// CHECK: c-index-api-loadTU-test.m:54:18: UnexposedExpr=bee:47:8 Extent=[54:18 - 54:36]
+// CHECK: c-index-api-loadTU-test.m:54:33: DeclRefExpr=bee:47:8 Extent=[54:33 - 54:36]
+
diff --git a/test/Index/cindex-from-source.m b/test/Index/cindex-from-source.m
index 6c5d936..86e794d 100644
--- a/test/Index/cindex-from-source.m
+++ b/test/Index/cindex-from-source.m
@@ -1,5 +1,5 @@
-// RUN: echo 'typedef int t0;' > %t.pfx.h
-// RUN: %clang -x objective-c-header %t.pfx.h -o %t.pfx.h.gch
+
+// RUN: %clang -x objective-c-header %S/Inputs/cindex-from-source.h -o %t.pfx.h.gch
// RUN: c-index-test -test-load-source local %s -include %t.pfx.h > %t
// RUN: FileCheck %s < %t
// CHECK: cindex-from-source.m:{{.*}}:{{.*}}: StructDecl=s0:{{.*}}:{{.*}}
diff --git a/test/Index/cindex-on-invalid.m b/test/Index/cindex-on-invalid.m
index 651c40a..7e190eb 100644
--- a/test/Index/cindex-on-invalid.m
+++ b/test/Index/cindex-on-invalid.m
@@ -1,6 +1,5 @@
// RUN: not c-index-test -test-load-source local %s > %t 2> %t.err
// RUN: FileCheck %s < %t.err
-
// CHECK: error: expected identifier or '('
// CHECK: Unable to load translation unit!
diff --git a/test/Index/code-complete-errors.c b/test/Index/code-complete-errors.c
index 520a8c8..29c2a86 100644
--- a/test/Index/code-complete-errors.c
+++ b/test/Index/code-complete-errors.c
@@ -7,7 +7,7 @@ struct s {
struct s s0 = { y: 5 }; // CHECK: code-complete-errors.c:7:20: warning: use of GNU old-style field designator extension
// CHECK: FIX-IT: Replace [7:17 - 7:19] with ".y = "
int f(int *ptr1, float *ptr2) {
- return ptr1 != ptr2; // CHECK: code-complete-errors.c:10:15:[10:10 - 10:14][10:18 - 10:22]: warning: comparison of distinct pointer types ('int *' and 'float *')
+ return ptr1 != ptr2; // CHECK: code-complete-errors.c:10:15:{10:10-10:14}{10:18-10:22}: warning: comparison of distinct pointer types ('int *' and 'float *')
}
void g() { }
diff --git a/test/Index/linkage.c b/test/Index/linkage.c
new file mode 100644
index 0000000..b597c26
--- /dev/null
+++ b/test/Index/linkage.c
@@ -0,0 +1,23 @@
+// RUN: c-index-test -test-print-linkage-source %s | FileCheck %s
+
+enum Baz { Qux = 0 };
+int x;
+void foo();
+static int w;
+void bar(int y) {
+ static int z;
+ int k;
+}
+extern int n;
+
+// CHECK: EnumDecl=Baz:3:6 (Definition)linkage=External
+// CHECK: EnumConstantDecl=Qux:3:12 (Definition)linkage=External
+// CHECK: VarDecl=x:4:5linkage=External
+// CHECK: FunctionDecl=foo:5:6linkage=External
+// CHECK: VarDecl=w:6:12linkage=External
+// CHECK: FunctionDecl=bar:7:6 (Definition)linkage=External
+// CHECK: ParmDecl=y:7:14 (Definition)linkage=External
+// CHECK: VarDecl=z:8:14 (Definition)linkage=External
+// CHECK: VarDecl=k:9:7 (Definition)linkage=External
+// CHECK: VarDecl=n:11:12
+
diff --git a/test/Lexer/constants.c b/test/Lexer/constants.c
index 104a3a2..b833e7b 100644
--- a/test/Lexer/constants.c
+++ b/test/Lexer/constants.c
@@ -38,20 +38,20 @@ char f = 'abcd'; // ignored.
float t0[] = {
1.9e20f,
1.9e-20f,
- 1.9e50f, // expected-error {{too large}}
- 1.9e-50f, // expected-error {{too small}}
+ 1.9e50f, // expected-warning {{too large}}
+ 1.9e-50f, // expected-warning {{too small}}
-1.9e20f,
-1.9e-20f,
- -1.9e50f, // expected-error {{too large}}
- -1.9e-50f // expected-error {{too small}}
+ -1.9e50f, // expected-warning {{too large}}
+ -1.9e-50f // expected-warning {{too small}}
};
double t1[] = {
1.9e50,
1.9e-50,
- 1.9e500, // expected-error {{too large}}
- 1.9e-500, // expected-error {{too small}}
+ 1.9e500, // expected-warning {{too large}}
+ 1.9e-500, // expected-warning {{too small}}
-1.9e50,
-1.9e-50,
- -1.9e500, // expected-error {{too large}}
- -1.9e-500 // expected-error {{too small}}
+ -1.9e500, // expected-warning {{too large}}
+ -1.9e-500 // expected-warning {{too small}}
};
diff --git a/test/PCH/Inputs/namespaces.h b/test/PCH/Inputs/namespaces.h
new file mode 100644
index 0000000..1bab746
--- /dev/null
+++ b/test/PCH/Inputs/namespaces.h
@@ -0,0 +1,13 @@
+// Header for PCH test namespaces.cpp
+
+namespace N1 {
+ typedef int t1;
+}
+
+namespace N1 {
+ typedef int t2;
+}
+
+namespace N2 {
+ typedef float t1;
+}
diff --git a/test/PCH/namespaces.cpp b/test/PCH/namespaces.cpp
new file mode 100644
index 0000000..eef9e06
--- /dev/null
+++ b/test/PCH/namespaces.cpp
@@ -0,0 +1,14 @@
+// Test this without pch.
+// RUN: %clang_cc1 -x c++ -include %S/Inputs/namespaces.h -fsyntax-only %s
+
+// Test with pch.
+// RUN: %clang_cc1 -x c++ -emit-pch -o %t %S/Inputs/namespaces.h
+// RUN: %clang_cc1 -x c++ -include-pch %t -fsyntax-only %s
+
+int int_val;
+N1::t1 *ip1 = &int_val;
+N1::t2 *ip2 = &int_val;
+
+float float_val;
+namespace N2 { }
+N2::t1 *fp1 = &float_val;
diff --git a/test/Parser/MicrosoftExtensions.c b/test/Parser/MicrosoftExtensions.c
index 082929f..0b2733e 100644
--- a/test/Parser/MicrosoftExtensions.c
+++ b/test/Parser/MicrosoftExtensions.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions -x objective-c++ %s
+// RUN: %clang_cc1 -triple i386-mingw32 -fsyntax-only -verify -fms-extensions -x objective-c++ %s
__stdcall int func0();
int __stdcall func();
typedef int (__cdecl *tptr)();
diff --git a/test/Parser/cxx-decl.cpp b/test/Parser/cxx-decl.cpp
index f37604c..c8f2c0b 100644
--- a/test/Parser/cxx-decl.cpp
+++ b/test/Parser/cxx-decl.cpp
@@ -58,3 +58,7 @@ struct test4 {
int y;
int z // expected-error {{expected ';' at end of declaration list}}
};
+
+// PR5825
+struct test5 {};
+::new(static_cast<void*>(0)) test5; // expected-error {{expected unqualified-id}}
diff --git a/test/Parser/cxx-template-argument.cpp b/test/Parser/cxx-template-argument.cpp
index 80389a0..532b4c9 100644
--- a/test/Parser/cxx-template-argument.cpp
+++ b/test/Parser/cxx-template-argument.cpp
@@ -5,5 +5,5 @@ template<typename T> struct A {};
// Check for template argument lists followed by junk
// FIXME: The diagnostics here aren't great...
A<int+> int x; // expected-error {{expected '>'}} expected-error {{expected unqualified-id}}
-A<int x; // expected-error {{expected '>'}} expected-error {{C++ requires a type specifier for all declarations}}
+A<int x; // expected-error {{expected '>'}}
diff --git a/test/Parser/knr_parameter_attributes.c b/test/Parser/knr_parameter_attributes.c
new file mode 100644
index 0000000..fb975cb
--- /dev/null
+++ b/test/Parser/knr_parameter_attributes.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -W -Wall -Werror -verify %s
+
+int f(int i __attribute__((__unused__)))
+{
+ return 0;
+}
+int g(i)
+ int i __attribute__((__unused__));
+{
+ return 0;
+}
diff --git a/test/Preprocessor/directive-invalid.c b/test/Preprocessor/directive-invalid.c
new file mode 100644
index 0000000..86cd253
--- /dev/null
+++ b/test/Preprocessor/directive-invalid.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -E -verify %s
+// rdar://7683173
+
+#define r_paren )
+#if defined( x r_paren // expected-error {{missing ')' after 'defined'}} \
+ // expected-note {{to match this '('}}
+#endif
diff --git a/test/Rewriter/dllimport-typedef.c b/test/Rewriter/dllimport-typedef.c
new file mode 100644
index 0000000..28d2e29
--- /dev/null
+++ b/test/Rewriter/dllimport-typedef.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-NEG %s
+// RUN: %clang_cc1 -triple i686-pc-win32 -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-POS %s
+
+// Do not report an error with including dllimport in the typedef when -fms-extensions is specified.
+// Addresses <rdar://problem/7653870>.
+typedef __declspec(dllimport) int CB(void);
+
+// This function is added just to trigger a diagnostic. This way we can test how many
+// diagnostics we expect.
+void bar() { return 1; }
+
+// CHECK-NEG: warning: void function 'bar' should not return a value
+// CHECK-NEG: 1 diagnostic generated
+// CHECK-POS: warning: 'dllimport' attribute only applies to variable and function type
+// CHECK-POS: warning: void function 'bar' should not return a value
+// CHECK-POS: 2 diagnostics generated
+
diff --git a/test/Rewriter/missing-dllimport.c b/test/Rewriter/missing-dllimport.c
new file mode 100644
index 0000000..d2356bd
--- /dev/null
+++ b/test/Rewriter/missing-dllimport.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -fms-extensions -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-NEG %s
+// RUN: %clang_cc1 -triple i686-pc-win32 -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-POS %s
+
+// Do not report that 'foo()' is redeclared without dllimport attribute with -fms-extensions
+// specified. Addresses <rdar://problem/7653912>.
+
+__declspec(dllimport) int __cdecl foo(void);
+inline int __cdecl foo() { return 0; }
+
+// This function is added just to trigger a diagnostic. This way we can test how many
+// diagnostics we expect.
+void bar() { return 1; }
+
+// CHECK-NEG: warning: void function 'bar' should not return a value
+// CHECK-NEG: 1 diagnostic generated
+// CHECK-POS: warning: 'foo' redeclared without dllimport attribute: previous dllimport ignored
+// CHECK-POS: warning: void function 'bar' should not return a value
+// CHECK-POS: 2 diagnostics generated
+
diff --git a/test/Rewriter/rewrite-block-pointer.mm b/test/Rewriter/rewrite-block-pointer.mm
index b03b7a9..212b236 100644
--- a/test/Rewriter/rewrite-block-pointer.mm
+++ b/test/Rewriter/rewrite-block-pointer.mm
@@ -1,7 +1,10 @@
// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
-// RUN: FileCheck -check-prefix LP --input-file=%t-rw.cpp %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
// radar 7638400
+typedef void * id;
+void *sel_registerName(const char *);
+
@interface X
@end
@@ -13,4 +16,45 @@ static void enumerateIt(void (^block)(id, id, char *)) {
}
@end
-// CHECK-LP: static void enumerateIt(void (*)(id, id, char *));
+// radar 7651312
+void apply(void (^block)(int));
+
+static void x(int (^cmp)(int, int)) {
+ x(cmp);
+}
+
+static void y(int (^cmp)(int, int)) {
+ apply(^(int sect) {
+ x(cmp);
+ });
+}
+
+// radar 7659483
+void *_Block_copy(const void *aBlock);
+void x(void (^block)(void)) {
+ block = ((__typeof(block))_Block_copy((const void *)(block)));
+}
+
+// radar 7682763
+@interface Y {
+@private
+ id _private;
+}
+- (void (^)(void))f;
+@end
+
+typedef void (^void_block_t)(void);
+
+@interface YY {
+ void_block_t __completion;
+}
+@property (copy) void_block_t f;
+@end
+
+@implementation Y
+- (void (^)(void))f {
+ return [_private f];
+}
+
+@end
+
diff --git a/test/Rewriter/rewrite-byref-in-nested-blocks.mm b/test/Rewriter/rewrite-byref-in-nested-blocks.mm
new file mode 100644
index 0000000..a8f5b14
--- /dev/null
+++ b/test/Rewriter/rewrite-byref-in-nested-blocks.mm
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// radar 7692350
+
+void f(void (^block)(void));
+
+@interface X {
+ int y;
+}
+- (void)foo;
+@end
+
+@implementation X
+- (void)foo {
+ __block int kerfluffle;
+ // radar 7692183
+ __block x;
+ f(^{
+ f(^{
+ y = 42;
+ kerfluffle = 1;
+ x = 2;
+ });
+ });
+}
+@end
diff --git a/test/Rewriter/rewrite-implementation.mm b/test/Rewriter/rewrite-implementation.mm
index 608707c..c1d89a3 100644
--- a/test/Rewriter/rewrite-implementation.mm
+++ b/test/Rewriter/rewrite-implementation.mm
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
-// RUN: %clang_cc1 -DSEL="void *" -S %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
// radar 7649577
@interface a
diff --git a/test/Rewriter/rewrite-nested-blocks-1.mm b/test/Rewriter/rewrite-nested-blocks-1.mm
new file mode 100644
index 0000000..582f5f4
--- /dev/null
+++ b/test/Rewriter/rewrite-nested-blocks-1.mm
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// radar 7696893
+
+void *sel_registerName(const char *);
+
+void f(void (^block)(void));
+void f2(id);
+void f3(int);
+char f4(id, id);
+
+@interface Baz
+- (void)b:(void (^)(void))block;
+@end
+
+@interface Bar
+@end
+
+@interface Foo {
+ int _x;
+}
+@end
+
+@implementation Foo
+- (void)method:(Bar *)up {
+ Baz *down;
+ int at;
+ id cq;
+ __block char didit = 'a';
+ __block char upIsFinished = 'b';
+ f(^{
+ id old_cq;
+ f2(cq);
+ [down b:^{
+ [down b:^{
+ f(^{
+ didit = f4(up, down);
+ upIsFinished = 'c';
+ self->_x++;
+ });
+ }];
+ }];
+ f2(old_cq);
+ f3(at);
+ });
+}
+@end
diff --git a/test/Rewriter/rewrite-nested-blocks.mm b/test/Rewriter/rewrite-nested-blocks.mm
new file mode 100644
index 0000000..1a6bcdd
--- /dev/null
+++ b/test/Rewriter/rewrite-nested-blocks.mm
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// radar 7682149
+
+
+void f(void (^block)(void));
+
+@interface X {
+ int y;
+}
+- (void)foo;
+@end
+
+@implementation X
+- (void)foo {
+ f(^{
+ f(^{
+ f(^{
+ y=42;
+ });
+ });
+});
+
+}
+@end
+
+struct S {
+ int y;
+};
+
+void foo () {
+ struct S *SELF;
+ f(^{
+ f(^{
+ SELF->y = 42;
+ });
+ });
+}
+
+// radar 7692419
+@interface Bar
+@end
+
+void f(Bar *);
+void q(void (^block)(void));
+
+void x() {
+ void (^myblock)(Bar *b) = ^(Bar *b) {
+ q(^{
+ f(b);
+ });
+ };
+
+ Bar *b = (Bar *)42;
+ myblock(b);
+}
diff --git a/test/Rewriter/rewrite-property-attributes.mm b/test/Rewriter/rewrite-property-attributes.mm
new file mode 100644
index 0000000..41f457c
--- /dev/null
+++ b/test/Rewriter/rewrite-property-attributes.mm
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// radar 7214439
+
+typedef void (^void_block_t)(void);
+
+@interface Y {
+ void_block_t __completion;
+ Y* YVAR;
+ id ID;
+}
+@property (copy) void_block_t completionBlock;
+@property (retain) Y* Yblock;
+@property (copy) id ID;
+@end
+
+@implementation Y
+@synthesize completionBlock=__completion;
+@synthesize Yblock = YVAR;
+@synthesize ID;
+@end
+
diff --git a/test/Rewriter/rewrite-qualified-id.mm b/test/Rewriter/rewrite-qualified-id.mm
new file mode 100644
index 0000000..fe3607d
--- /dev/null
+++ b/test/Rewriter/rewrite-qualified-id.mm
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// radar 7680953
+
+typedef void * id;
+
+@protocol foo
+@end
+
+@interface CL
+{
+ id <foo> changeSource;
+ CL <foo>* changeSource1;
+}
+@end
+
+typedef struct x
+{
+ id <foo> changeSource;
+} x;
+
diff --git a/test/Rewriter/rewrite-rewritten-initializer.mm b/test/Rewriter/rewrite-rewritten-initializer.mm
new file mode 100644
index 0000000..80ad7fc
--- /dev/null
+++ b/test/Rewriter/rewrite-rewritten-initializer.mm
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// radar 7669784
+
+typedef void * id;
+void *sel_registerName(const char *);
+
+@interface NSMutableString
+- (NSMutableString *)string;
+@end
+
+@interface Z
+@end
+
+@implementation Z
+
+- (void)x {
+ id numbers;
+ int i, numbersCount = 42;
+ __attribute__((__blocks__(byref))) int blockSum = 0;
+ void (^add)(id n, int idx, char *stop) = ^(id n, int idx, char *stop) { };
+ [numbers enumerateObjectsUsingBlock:add];
+ NSMutableString *forwardAppend = [NSMutableString string];
+ __attribute__((__blocks__(byref))) NSMutableString *blockAppend = [NSMutableString string];
+}
+
+@end
+
diff --git a/test/Rewriter/rewrite-unique-block-api.mm b/test/Rewriter/rewrite-unique-block-api.mm
index 780a3f0..130f514 100644
--- a/test/Rewriter/rewrite-unique-block-api.mm
+++ b/test/Rewriter/rewrite-unique-block-api.mm
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
-// RUN: FileCheck -check-prefix LP --input-file=%t-rw.cpp %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
// radar 7630551
void f(void (^b)(char c));
@@ -23,9 +23,3 @@ void f(void (^b)(char c));
f(^(char x) { });
}
@end
-
-// CHECK-LP: struct __a__processStuff_block_impl_0
-// CHECK-LP: static void __a__processStuff_block_func_0
-
-// CHECK-LP: struct __b__processStuff_block_impl_0
-// CHECK-LP: static void __b__processStuff_block_func_0
diff --git a/test/Sema/align-x86.c b/test/Sema/align-x86.c
index f67adec..c9a6398 100644
--- a/test/Sema/align-x86.c
+++ b/test/Sema/align-x86.c
@@ -12,3 +12,9 @@ short chk2[__alignof__(long long) == 8 ? 1 : -1];
_Complex double g3;
short chk1[__alignof__(g3) == 8 ? 1 : -1];
short chk2[__alignof__(_Complex double) == 8 ? 1 : -1];
+
+// PR6362
+struct __attribute__((packed)) {unsigned int a} g4;
+short chk1[__alignof__(g4) == 1 ? 1 : -1];
+short chk2[__alignof__(g4.a) == 1 ? 1 : -1];
+
diff --git a/test/Sema/arg-duplicate.c b/test/Sema/arg-duplicate.c
index ca091eb..feeb458 100644
--- a/test/Sema/arg-duplicate.c
+++ b/test/Sema/arg-duplicate.c
@@ -2,7 +2,8 @@
int f3(y, x,
x) // expected-error {{redefinition of parameter}}
- int y, x,
+ int y,
+ x, // expected-note {{previous declaration is here}}
x; // expected-error {{redefinition of parameter}}
{
return x + y;
diff --git a/test/Sema/block-args.c b/test/Sema/block-args.c
index a07c82e..970c60d 100644
--- a/test/Sema/block-args.c
+++ b/test/Sema/block-args.c
@@ -6,7 +6,8 @@ void test() {
take(^(int x){});
take(^(int x, int y){});
take(^(int x, int y){});
- take(^(int x, int x){}); // expected-error {{redefinition of parameter 'x'}}
+ take(^(int x, // expected-note {{previous declaration is here}}
+ int x){}); // expected-error {{redefinition of parameter 'x'}}
take(^(int x) { return x+1; });
diff --git a/test/Sema/callingconv.c b/test/Sema/callingconv.c
index 0752606..92a2057 100644
--- a/test/Sema/callingconv.c
+++ b/test/Sema/callingconv.c
@@ -36,3 +36,11 @@ void (__attribute__((cdecl)) *pctest2)() = ctest2;
typedef void (__attribute__((fastcall)) *Handler) (float *);
Handler H = foo;
+// PR6361
+void ctest3();
+void __attribute__((cdecl)) ctest3() {}
+
+// PR6408
+typedef __attribute__((stdcall)) void (*PROC)();
+PROC __attribute__((cdecl)) ctest4(const char *x) {}
+
diff --git a/test/Sema/conversion.c b/test/Sema/conversion.c
index 8b93a46..addedd9 100644
--- a/test/Sema/conversion.c
+++ b/test/Sema/conversion.c
@@ -279,3 +279,11 @@ void test_7631400(void) {
// This should show up despite the caret being inside a macro substitution
char s = LONG_MAX; // expected-warning {{implicit cast loses integer precision: 'long' to 'char'}}
}
+
+// <rdar://problem/7676608>: assertion for compound operators with non-integral RHS
+void f7676608(int);
+void test_7676608(void) {
+ float q = 0.7f;
+ char c = 5;
+ f7676608(c *= q);
+}
diff --git a/test/Sema/declspec.c b/test/Sema/declspec.c
index d9f4157..1c87a0e 100644
--- a/test/Sema/declspec.c
+++ b/test/Sema/declspec.c
@@ -31,3 +31,8 @@ struct test1 {
void test2() {}
+
+// PR6423
+struct test3s {
+} // expected-error {{expected ';' after struct}}
+typedef int test3g;
diff --git a/test/Sema/dllimport-dllexport.c b/test/Sema/dllimport-dllexport.c
index a1e7a18..eea2f6f 100644
--- a/test/Sema/dllimport-dllexport.c
+++ b/test/Sema/dllimport-dllexport.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple i386-mingw32 -fsyntax-only -verify %s
inline void __attribute__((dllexport)) foo1(){} // expected-warning{{dllexport attribute ignored}}
inline void __attribute__((dllimport)) foo2(){} // expected-warning{{dllimport attribute ignored}}
@@ -16,3 +16,21 @@ typedef int __attribute__((dllimport)) type7; // expected-warning{{'dllimport' a
void __attribute__((dllimport)) foo6();
void foo6(){} // expected-warning {{'foo6' redeclared without dllimport attribute: previous dllimport ignored}}
+
+// PR6269
+inline void __declspec(dllexport) foo7(){} // expected-warning{{dllexport attribute ignored}}
+inline void __declspec(dllimport) foo8(){} // expected-warning{{dllimport attribute ignored}}
+
+void __declspec(dllimport) foo9(){} // expected-error{{dllimport attribute can be applied only to symbol declaration}}
+
+void __declspec(dllimport) __declspec(dllexport) foo10(); // expected-warning{{dllimport attribute ignored}}
+
+void __declspec(dllexport) foo11();
+void __declspec(dllimport) foo11(); // expected-warning{{dllimport attribute ignored}}
+
+typedef int __declspec(dllexport) type1; // expected-warning{{'dllexport' attribute only applies to variable and function types}}
+
+typedef int __declspec(dllimport) type2; // expected-warning{{'dllimport' attribute only applies to variable and function}}
+
+void __declspec(dllimport) foo12();
+void foo12(){} // expected-warning {{'foo12' redeclared without dllimport attribute: previous dllimport ignored}}
diff --git a/test/Sema/enum.c b/test/Sema/enum.c
index 9b46500..6177edf 100644
--- a/test/Sema/enum.c
+++ b/test/Sema/enum.c
@@ -9,7 +9,8 @@ enum g { // too negative
c = -2147483649, // expected-warning {{ISO C restricts enumerator values to range of 'int'}}
d = 2147483647 };
enum h { e = -2147483648, // too pos
- f = 2147483648 // expected-warning {{ISO C restricts enumerator values to range of 'int'}}
+ f = 2147483648, // expected-warning {{ISO C restricts enumerator values to range of 'int'}}
+ i = 0xFFFF0000 // expected-warning {{too large}}
};
// minll maxull
diff --git a/test/Sema/format-strings.c b/test/Sema/format-strings.c
index f1fa658..4db775f 100644
--- a/test/Sema/format-strings.c
+++ b/test/Sema/format-strings.c
@@ -55,7 +55,7 @@ void check_conditional_literal(const char* s, int i) {
printf(i == 1 ? "yes" : "no"); // no-warning
printf(i == 0 ? (i == 1 ? "yes" : "no") : "dont know"); // no-warning
printf(i == 0 ? (i == 1 ? s : "no") : "dont know"); // expected-warning{{format string is not a string literal}}
- printf("yes" ?: "no %d", 1); // expected-warning{{more data arguments than format specifiers}}
+ printf("yes" ?: "no %d", 1); // expected-warning{{data argument not used by format string}}
}
void check_writeback_specifier()
@@ -145,6 +145,7 @@ void torture(va_list v8) {
}
void test10(int x, float f, int i, long long lli) {
+ printf("%s"); // expected-warning{{more '%' conversions than data arguments}}
printf("%@", 12); // expected-warning{{invalid conversion specifier '@'}}
printf("\0"); // expected-warning{{format string contains '\0' within the string body}}
printf("xs\0"); // expected-warning{{format string contains '\0' within the string body}}
@@ -155,7 +156,7 @@ void test10(int x, float f, int i, long long lli) {
printf("%**\n"); // expected-warning{{invalid conversion specifier '*'}}
printf("%n", &i); // expected-warning{{use of '%n' in format string discouraged (potentially insecure)}}
printf("%d%d\n", x); // expected-warning{{more '%' conversions than data arguments}}
- printf("%d\n", x, x); // expected-warning{{more data arguments than format specifiers}}
+ printf("%d\n", x, x); // expected-warning{{data argument not used by format string}}
printf("%W%d%Z\n", x, x, x); // expected-warning{{invalid conversion specifier 'W'}} expected-warning{{invalid conversion specifier 'Z'}}
printf("%"); // expected-warning{{incomplete format specifier}}
printf("%.d", x); // no-warning
@@ -169,6 +170,8 @@ void test10(int x, float f, int i, long long lli) {
printf("%d", (long long) 10); // expected-warning{{conversion specifies type 'int' but the argument has type 'long long'}}
printf("%Lf\n", (long double) 1.0); // no-warning
printf("%f\n", (long double) 1.0); // expected-warning{{conversion specifies type 'double' but the argument has type 'long double'}}
+ // The man page says that a zero precision is okay.
+ printf("%.0Lf", (long double) 1.0); // no-warning
}
void test11(void *p, char *s) {
@@ -204,3 +207,34 @@ void test_asl(aslclient asl) {
// <rdar://problem/7595366>
typedef enum { A } int_t;
void f0(int_t x) { printf("%d\n", x); }
+
+// Unicode test cases. These are possibly specific to Mac OS X. If so, they should
+// eventually be moved into a separate test.
+typedef __WCHAR_TYPE__ wchar_t;
+
+void test_unicode_conversions(wchar_t *s) {
+ printf("%S", s); // no-warning
+ printf("%s", s); // expected-warning{{conversion specifies type 'char *' but the argument has type 'wchar_t *'}}
+ printf("%C", s[0]); // no-warning
+ printf("%c", s[0]);
+ // FIXME: This test reports inconsistent results. On Windows, '%C' expects
+ // 'unsigned short'.
+ // printf("%C", 10);
+ // FIXME: we report the expected type as 'int*' instead of 'wchar_t*'
+ printf("%S", "hello"); // expected-warning{{but the argument has type 'char *'}}
+}
+
+// Mac OS X supports positional arguments in format strings.
+// This is an IEEE extension (IEEE Std 1003.1).
+// FIXME: This is probably not portable everywhere.
+void test_positional_arguments() {
+ printf("%0$", (int)2); // expected-warning{{position arguments in format strings start counting at 1 (not 0)}}
+ printf("%1$*0$d", (int) 2); // expected-warning{{position arguments in format strings start counting at 1 (not 0)}}
+ printf("%1$d", (int) 2); // no-warning
+ printf("%1$d", (int) 2, 2); // expected-warning{{data argument not used by format string}}
+ printf("%1$d%1$f", (int) 2); // expected-warning{{conversion specifies type 'double' but the argument has type 'int'}}
+ printf("%1$2.2d", (int) 2); // no-warning
+ printf("%2$*1$.2d", (int) 2, (int) 3); // no-warning
+ printf("%2$*8$d", (int) 2, (int) 3); // expected-warning{{specified field width is missing a matching 'int' argument}}
+}
+
diff --git a/test/Sema/inline.c b/test/Sema/inline.c
index 3c99f24..b4795d3 100644
--- a/test/Sema/inline.c
+++ b/test/Sema/inline.c
@@ -1,6 +1,22 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=gnu89 -fsyntax-only -verify %s
// Check that we don't allow illegal uses of inline
inline int a; // expected-error{{'inline' can only appear on functions}}
typedef inline int b; // expected-error{{'inline' can only appear on functions}}
int d(inline int a); // expected-error{{'inline' can only appear on functions}}
+
+// PR5253
+// GNU Extension: check that we can redefine an extern inline function
+extern inline int f(int a) {return a;}
+int f(int b) {return b;} // expected-note{{previous definition is here}}
+// And now check that we can't redefine a normal function
+int f(int c) {return c;} // expected-error{{redefinition of 'f'}}
+
+// Check that we can redefine an extern inline function as a static function
+extern inline int g(int a) {return a;}
+static int g(int b) {return b;}
+
+// Check that we ensure the types of the two definitions are the same
+extern inline int h(int a) {return a;} // expected-note{{previous definition is here}}
+int h(short b) {return b;} // expected-error{{conflicting types for 'h'}}
+
diff --git a/test/Sema/overloadable-complex.c b/test/Sema/overloadable-complex.c
index e8dbf3a..770a972 100644
--- a/test/Sema/overloadable-complex.c
+++ b/test/Sema/overloadable-complex.c
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-char *foo(float) __attribute__((__overloadable__)); // expected-note 3 {{candidate function}}
+char *foo(float) __attribute__((__overloadable__));
void test_foo_1(float fv, double dv, float _Complex fc, double _Complex dc) {
char *cp1 = foo(fv);
@@ -9,20 +9,20 @@ void test_foo_1(float fv, double dv, float _Complex fc, double _Complex dc) {
char *cp4 = foo(dc);
}
-int *foo(float _Complex) __attribute__((__overloadable__)); // expected-note 3 {{candidate function}}
+int *foo(float _Complex) __attribute__((__overloadable__));
void test_foo_2(float fv, double dv, float _Complex fc, double _Complex dc) {
char *cp1 = foo(fv);
- char *cp2 = foo(dv); // expected-error{{call to 'foo' is ambiguous; candidates are:}}
+ char *cp2 = foo(dv);
int *ip = foo(fc);
- int *lp = foo(dc); // expected-error{{call to 'foo' is ambiguous; candidates are:}}
+ int *lp = foo(dc);
}
-long *foo(double _Complex) __attribute__((__overloadable__)); // expected-note {{candidate function}}
+long *foo(double _Complex) __attribute__((__overloadable__));
void test_foo_3(float fv, double dv, float _Complex fc, double _Complex dc) {
char *cp1 = foo(fv);
- char *cp2 = foo(dv); // expected-error{{call to 'foo' is ambiguous; candidates are:}}
+ char *cp2 = foo(dv);
int *ip = foo(fc);
long *lp = foo(dc);
}
diff --git a/test/Sema/static-init.c b/test/Sema/static-init.c
index 8011943..b4de927 100644
--- a/test/Sema/static-init.c
+++ b/test/Sema/static-init.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -triple i386-pc-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
-#include <stdint.h>
+typedef __typeof((int*) 0 - (int*) 0) intptr_t;
static int f = 10;
static int b = f; // expected-error {{initializer element is not a compile-time constant}}
diff --git a/test/Sema/switch.c b/test/Sema/switch.c
index 2690ad2..e63a194 100644
--- a/test/Sema/switch.c
+++ b/test/Sema/switch.c
@@ -223,3 +223,41 @@ void test12() {
break;
}
}
+
+// <rdar://problem/7643909>
+typedef enum {
+ val1,
+ val2,
+ val3
+} my_type_t;
+
+int test13(my_type_t t) {
+ switch(t) { // expected-warning{{enumeration value 'val3' not handled in switch}}
+ case val1:
+ return 1;
+ case val2:
+ return 2;
+ }
+ return -1;
+}
+
+// <rdar://problem/7658121>
+enum {
+ EC0 = 0xFFFF0000,
+ EC1 = 0xFFFF0001,
+};
+
+int test14(int a) {
+ switch(a) {
+ case EC0: return 0;
+ case EC1: return 1;
+ }
+ return 0;
+}
+
+void f1(unsigned x) {
+ switch (x) {
+ case -1: break;
+ default: break;
+ }
+}
diff --git a/test/Sema/warn-unreachable.c b/test/Sema/warn-unreachable.c
index 1eef637..10ed696 100644
--- a/test/Sema/warn-unreachable.c
+++ b/test/Sema/warn-unreachable.c
@@ -35,8 +35,8 @@ void test2() {
dead(); // expected-warning {{will never be executed}}
case 3:
- live()
- + // expected-warning {{will never be executed}}
+ live() // expected-warning {{will never be executed}}
+ +
halt();
dead();
diff --git a/test/Sema/warn-unused-function.c b/test/Sema/warn-unused-function.c
index 178527f..b52f676 100644
--- a/test/Sema/warn-unused-function.c
+++ b/test/Sema/warn-unused-function.c
@@ -13,4 +13,18 @@ extern void f3() { } // expected-warning{{unused}}
// FIXME: This will trigger a warning when it should not.
// Update once PR6281 is fixed.
//inline static void f4();
-//void f4() { } \ No newline at end of file
+//void f4() { }
+
+static void __attribute__((used)) f5() {}
+static void f6();
+static void __attribute__((used)) f6();
+static void f6() {};
+
+static void f7(void);
+void f8(void(*a0)(void));
+void f9(void) { f8(f7); }
+static void f7(void) {}
+
+__attribute__((unused)) static void bar(void);
+void bar(void) { }
+
diff --git a/test/Sema/warn-unused-variables.c b/test/Sema/warn-unused-variables.c
index 3661506..58e52b1 100644
--- a/test/Sema/warn-unused-variables.c
+++ b/test/Sema/warn-unused-variables.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wunused-variable -fblocks -verify %s
struct s0 {
unsigned int i;
@@ -17,3 +17,16 @@ void f1(void) {
(void)sizeof(i);
return;
}
+
+// PR5933
+int f2() {
+ int X = 4; // Shouldn't have a bogus 'unused variable X' warning.
+ return Y + X; // expected-error {{use of undeclared identifier 'Y'}}
+}
+
+int f3() {
+ int X1 = 4;
+ (void)(Y1 + X1); // expected-error {{use of undeclared identifier 'Y1'}}
+ (void)(^() { int X = 4; }); // expected-warning{{unused}}
+ (void)(^() { int X = 4; return Y + X; }); // expected-error {{use of undeclared identifier 'Y'}}
+}
diff --git a/test/Sema/x86-attr-force-align-arg-pointer.c b/test/Sema/x86-attr-force-align-arg-pointer.c
index 9609fad..b406a77 100644
--- a/test/Sema/x86-attr-force-align-arg-pointer.c
+++ b/test/Sema/x86-attr-force-align-arg-pointer.c
@@ -14,5 +14,8 @@ void d(void);
void __attribute__((force_align_arg_pointer)) d(void) {}
// Attribute is ignored on function pointer types.
-void (__attribute__((force_align_arg_pointer)) *p)(); //expected-warning{{force_align_arg_pointer used on function pointer; attribute ignored}}
+void (__attribute__((force_align_arg_pointer)) *p)();
+typedef void (__attribute__((__force_align_arg_pointer__)) *p2)();
+// Attribute is also ignored on function typedefs.
+typedef void __attribute__((force_align_arg_pointer)) e(void);
diff --git a/test/SemaCXX/address-of-temporary.cpp b/test/SemaCXX/address-of-temporary.cpp
new file mode 100644
index 0000000..decdc95
--- /dev/null
+++ b/test/SemaCXX/address-of-temporary.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -Wno-error=address-of-temporary -verify %s
+struct X {
+ X();
+ X(int);
+ X(int, int);
+};
+
+void *f0() { return &X(); } // expected-warning{{taking the address of a temporary object}}
+void *f1() { return &X(1); } // expected-warning{{taking the address of a temporary object}}
+void *f2() { return &X(1, 2); } // expected-warning{{taking the address of a temporary object}}
+void *f3() { return &(X)1; } // expected-warning{{taking the address of a temporary object}}
+
diff --git a/test/SemaCXX/attr-weakref.cpp b/test/SemaCXX/attr-weakref.cpp
new file mode 100644
index 0000000..5773acc
--- /dev/null
+++ b/test/SemaCXX/attr-weakref.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// GCC will accept anything as the argument of weakref. Should we
+// check for an existing decl?
+static int a1() __attribute__((weakref ("foo")));
+static int a2() __attribute__((weakref, alias ("foo")));
+
+static int a3 __attribute__((weakref ("foo")));
+static int a4 __attribute__((weakref, alias ("foo")));
+
+// gcc rejects, clang accepts
+static int a5 __attribute__((alias ("foo"), weakref));
+
+// this is pointless, but accepted by gcc. We reject it.
+static int a6 __attribute__((weakref)); //expected-error {{weakref declaration of 'a6' must also have an alias attribute}}
+
+// gcc warns, clang rejects
+void f(void) {
+ static int a __attribute__((weakref ("v2"))); // expected-error {{declaration of 'a' must be in a global context}}
+}
+
+// both gcc and clang reject
+class c {
+ static int a __attribute__((weakref ("v2"))); // expected-error {{declaration of 'a' must be in a global context}}
+ static int b() __attribute__((weakref ("f3"))); // expected-error {{declaration of 'b' must be in a global context}}
+};
+int a7() __attribute__((weakref ("f1"))); // expected-error {{declaration of 'a7' must be static}}
+int a8 __attribute__((weakref ("v1"))); // expected-error {{declaration of 'a8' must be static}}
+
+// gcc accepts this
+int a9 __attribute__((weakref)); // expected-error {{declaration of 'a9' must be static}}
diff --git a/test/SemaCXX/blocks-1.cpp b/test/SemaCXX/blocks-1.cpp
new file mode 100644
index 0000000..d93997a
--- /dev/null
+++ b/test/SemaCXX/blocks-1.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks
+
+extern "C" int exit(int);
+
+typedef struct {
+ unsigned long ps[30];
+ int qs[30];
+} BobTheStruct;
+
+int main (int argc, const char * argv[]) {
+ BobTheStruct inny;
+ BobTheStruct outty;
+ BobTheStruct (^copyStruct)(BobTheStruct);
+ int i;
+
+ for(i=0; i<30; i++) {
+ inny.ps[i] = i * i * i;
+ inny.qs[i] = -i * i * i;
+ }
+
+ copyStruct = ^(BobTheStruct aBigStruct){ return aBigStruct; }; // pass-by-value intrinsically copies the argument
+
+ outty = copyStruct(inny);
+
+ if ( &inny == &outty ) {
+ exit(1);
+ }
+ for(i=0; i<30; i++) {
+ if ( (inny.ps[i] != outty.ps[i]) || (inny.qs[i] != outty.qs[i]) ) {
+ exit(1);
+ }
+ }
+
+ return 0;
+}
diff --git a/test/SemaCXX/complex-overload.cpp b/test/SemaCXX/complex-overload.cpp
index 3378755..2c057ac 100644
--- a/test/SemaCXX/complex-overload.cpp
+++ b/test/SemaCXX/complex-overload.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-char *foo(float); // expected-note 3 {{candidate function}}
+char *foo(float);
void test_foo_1(float fv, double dv, float _Complex fc, double _Complex dc) {
char *cp1 = foo(fv);
@@ -9,20 +9,20 @@ void test_foo_1(float fv, double dv, float _Complex fc, double _Complex dc) {
char *cp4 = foo(dc);
}
-int *foo(float _Complex); // expected-note 3 {{candidate function}}
+int *foo(float _Complex);
void test_foo_2(float fv, double dv, float _Complex fc, double _Complex dc) {
char *cp1 = foo(fv);
- char *cp2 = foo(dv); // expected-error{{call to 'foo' is ambiguous; candidates are:}}
+ char *cp2 = foo(dv);
int *ip = foo(fc);
- int *lp = foo(dc); // expected-error{{call to 'foo' is ambiguous; candidates are:}}
+ int *lp = foo(dc);
}
-long *foo(double _Complex); // expected-note {{candidate function}}
+long *foo(double _Complex);
void test_foo_3(float fv, double dv, float _Complex fc, double _Complex dc) {
char *cp1 = foo(fv);
- char *cp2 = foo(dv); // expected-error{{call to 'foo' is ambiguous; candidates are:}}
+ char *cp2 = foo(dv);
int *ip = foo(fc);
long *lp = foo(dc);
}
diff --git a/test/SemaCXX/composite-pointer-type.cpp b/test/SemaCXX/composite-pointer-type.cpp
index fdf838f..e8b0920 100644
--- a/test/SemaCXX/composite-pointer-type.cpp
+++ b/test/SemaCXX/composite-pointer-type.cpp
@@ -50,3 +50,11 @@ typedef double Matrix4[4][4];
bool f(Matrix4 m1, const Matrix4 m2) {
return m1 != m2;
}
+
+// PR6346
+bool f1(bool b, void **p, const void **q) {
+ if (p == q) // expected-warning{{comparison of distinct pointer types ('void **' and 'void const **') uses non-standard composite pointer type 'void const *const *'}}
+ return false;
+
+ return b? p : q; // expected-warning{{incompatible operand types ('void **' and 'void const **') use non-standard composite pointer type 'void const *const *'}}
+}
diff --git a/test/SemaCXX/condition.cpp b/test/SemaCXX/condition.cpp
index fe802d0..b3e862d 100644
--- a/test/SemaCXX/condition.cpp
+++ b/test/SemaCXX/condition.cpp
@@ -18,7 +18,8 @@ void test() {
while (struct S {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}} expected-note{{candidate constructor (the implicit copy constructor)}}
while (struct {} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{no viable conversion}} expected-error {{value of type 'struct <anonymous>' is not contextually convertible to 'bool'}} expected-note{{candidate constructor (the implicit copy constructor)}}
- switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{cannot initialize}}
+ switch (enum {E} x=0) ; // expected-error {{types may not be defined in conditions}} expected-error {{cannot initialize}} \
+ // expected-warning{{enumeration value 'E' not handled in switch}}
if (int x=0) { // expected-note 2 {{previous definition is here}}
int x; // expected-error {{redefinition of 'x'}}
diff --git a/test/SemaCXX/copy-constructor-error.cpp b/test/SemaCXX/copy-constructor-error.cpp
index 9cae775..9809bfc 100644
--- a/test/SemaCXX/copy-constructor-error.cpp
+++ b/test/SemaCXX/copy-constructor-error.cpp
@@ -10,3 +10,16 @@ void g() {
S a( f() );
}
+namespace PR6064 {
+ struct A {
+ A() { }
+ inline A(A&, int);
+ };
+
+ A::A(A&, int = 0) { }
+
+ void f() {
+ A const a;
+ A b(a);
+ }
+}
diff --git a/test/SemaCXX/dcl_init_aggr.cpp b/test/SemaCXX/dcl_init_aggr.cpp
index 861eb3d..461c60b 100644
--- a/test/SemaCXX/dcl_init_aggr.cpp
+++ b/test/SemaCXX/dcl_init_aggr.cpp
@@ -38,7 +38,7 @@ char cv[4] = { 'a', 's', 'd', 'f', 0 }; // expected-error{{excess elements in ar
// C++ [dcl.init.aggr]p7
struct TooFew { int a; char* b; int c; };
-TooFew too_few = { 1, "asdf" }; // okay
+TooFew too_few = { 1, "asdf" }; // expected-warning{{conversion from string literal to 'char *' is deprecated}}
struct NoDefaultConstructor { // expected-note 3 {{candidate constructor (the implicit copy constructor)}} \
// expected-note{{declared here}}
diff --git a/test/SemaCXX/default2.cpp b/test/SemaCXX/default2.cpp
index d2c44bd..e674260 100644
--- a/test/SemaCXX/default2.cpp
+++ b/test/SemaCXX/default2.cpp
@@ -16,7 +16,8 @@ void i()
}
-int f1(int i, int i, int j) { // expected-error {{redefinition of parameter 'i'}}
+int f1(int i, // expected-note {{previous declaration is here}}
+ int i, int j) { // expected-error {{redefinition of parameter 'i'}}
i = 17;
return j;
}
diff --git a/test/SemaCXX/destructor.cpp b/test/SemaCXX/destructor.cpp
index 6837cd4..ab3c809 100644
--- a/test/SemaCXX/destructor.cpp
+++ b/test/SemaCXX/destructor.cpp
@@ -40,9 +40,9 @@ struct F {
~F(); // expected-error {{destructor cannot be redeclared}}
};
-~; // expected-error {{expected the class name after '~' to name a destructor}}
+~; // expected-error {{expected a class name after '~' to name a destructor}}
~undef(); // expected-error {{expected the class name after '~' to name a destructor}}
-~operator+(int, int); // expected-error {{expected the class name after '~' to name a destructor}}
+~operator+(int, int); // expected-error {{expected a class name after '~' to name a destructor}}
~F(){} // expected-error {{destructor must be a non-static member function}}
struct G {
@@ -61,3 +61,20 @@ struct X {};
struct Y {
~X(); // expected-error {{expected the class name after '~' to name the enclosing class}}
};
+
+namespace PR6421 {
+ class T; // expected-note{{forward declaration}}
+
+ class QGenericArgument
+ {
+ template<typename U>
+ void foo(T t) // expected-error{{variable has incomplete type}}
+ { }
+
+ void disconnect()
+ {
+ T* t;
+ bob<QGenericArgument>(t); // expected-error{{undeclared identifier 'bob'}}
+ }
+ };
+}
diff --git a/test/SemaCXX/i-c-e-cxx.cpp b/test/SemaCXX/i-c-e-cxx.cpp
index 4f2f197..e8275d4 100644
--- a/test/SemaCXX/i-c-e-cxx.cpp
+++ b/test/SemaCXX/i-c-e-cxx.cpp
@@ -37,3 +37,8 @@ namespace pr6206 {
return str[0];
}
}
+
+// PR6373: default arguments don't count.
+void pr6373(const unsigned x = 0) {
+ unsigned max = 80 / x;
+}
diff --git a/test/SemaCXX/implicit-virtual-member-functions.cpp b/test/SemaCXX/implicit-virtual-member-functions.cpp
index 4ae9eae..1bb5adb 100644
--- a/test/SemaCXX/implicit-virtual-member-functions.cpp
+++ b/test/SemaCXX/implicit-virtual-member-functions.cpp
@@ -15,9 +15,9 @@ void B::f() { // expected-note {{implicit default destructor for 'struct B' firs
struct C : A { // expected-error {{no suitable member 'operator delete' in 'C'}}
C();
void operator delete(void *, int); // expected-note {{'operator delete' declared here}}
-}; // expected-note {{implicit default destructor for 'struct C' first required here}}
+};
-C::C() { }
+C::C() { } // expected-note {{implicit default destructor for 'struct 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}}
diff --git a/test/SemaCXX/invalid-member-expr.cpp b/test/SemaCXX/invalid-member-expr.cpp
index 666595c..7b17afb 100644
--- a/test/SemaCXX/invalid-member-expr.cpp
+++ b/test/SemaCXX/invalid-member-expr.cpp
@@ -6,7 +6,7 @@ void test() {
X x;
x.int; // expected-error{{expected unqualified-id}}
- x.~int(); // expected-error{{expected the class name}}
+ x.~int(); // expected-error{{expected a class name}}
x.operator; // expected-error{{missing type specifier after 'operator'}}
x.operator typedef; // expected-error{{missing type specifier after 'operator'}}
}
@@ -15,7 +15,7 @@ void test2() {
X *x;
x->int; // expected-error{{expected unqualified-id}}
- x->~int(); // expected-error{{expected the class name}}
+ x->~int(); // expected-error{{expected a class name}}
x->operator; // expected-error{{missing type specifier after 'operator'}}
x->operator typedef; // expected-error{{missing type specifier after 'operator'}}
}
diff --git a/test/SemaCXX/local-classes.cpp b/test/SemaCXX/local-classes.cpp
new file mode 100644
index 0000000..6799e58
--- /dev/null
+++ b/test/SemaCXX/local-classes.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace PR6382 {
+ int foo()
+ {
+ goto error;
+ {
+ struct BitPacker {
+ BitPacker() {}
+ };
+ BitPacker packer;
+ }
+
+ error:
+ return -1;
+ }
+}
+
+namespace PR6383 {
+ void test (bool gross)
+ {
+ struct compare_and_set
+ {
+ void operator() (const bool inner, const bool gross = false)
+ {
+ // the code
+ }
+ } compare_and_set2;
+
+ compare_and_set2 (false, gross);
+ }
+}
diff --git a/test/SemaCXX/member-name-lookup.cpp b/test/SemaCXX/member-name-lookup.cpp
index ff14416..94296e1 100644
--- a/test/SemaCXX/member-name-lookup.cpp
+++ b/test/SemaCXX/member-name-lookup.cpp
@@ -2,7 +2,7 @@
struct A {
int a; // expected-note 4{{member found by ambiguous name lookup}}
static int b;
- static int c; // expected-note 4{{member found by ambiguous name lookup}}
+ static int c; // expected-note 2{{member found by ambiguous name lookup}}
enum E { enumerator };
@@ -75,7 +75,7 @@ struct B2 : virtual A {
};
struct C2 : virtual A {
- int c; // expected-note 2{{member found by ambiguous name lookup}}
+ int c;
int d; // expected-note 2{{member found by ambiguous name lookup}}
enum E3 { enumerator3_2 }; // expected-note 2{{member found by ambiguous name lookup}}
@@ -93,7 +93,7 @@ struct G : F, D2 {
void test_virtual_lookup(D2 d2, G g) {
(void)d2.a;
(void)d2.b;
- d2.c; // expected-error{{member 'c' found in multiple base classes of different types}}
+ (void)d2.c; // okay
d2.d; // expected-error{{member 'd' found in multiple base classes of different types}}
d2.f(0); // okay
d2.static_f(0); // okay
@@ -112,7 +112,7 @@ void test_virtual_lookup(D2 d2, G g) {
void D2::test_virtual_lookup() {
(void)a;
(void)b;
- c; // expected-error{{member 'c' found in multiple base classes of different types}}
+ (void)c; // okay
d; // expected-error{{member 'd' found in multiple base classes of different types}}
f(0); // okay
static_f(0); // okay
diff --git a/test/SemaCXX/member-pointer.cpp b/test/SemaCXX/member-pointer.cpp
index 3d9d5b5e..d6050cd 100644
--- a/test/SemaCXX/member-pointer.cpp
+++ b/test/SemaCXX/member-pointer.cpp
@@ -12,8 +12,7 @@ int A::*pdi1;
int (::A::*pdi2);
int (A::*pfi)(int);
-int B::*pbi; // expected-error {{expected a class or namespace}} \
- // expected-error{{does not point into a class}}
+int B::*pbi; // expected-error {{expected a class or namespace}}
int C::*pci; // expected-error {{'pci' does not point into a class}}
void A::*pdv; // expected-error {{'pdv' declared as a member pointer to void}}
int& A::*pdr; // expected-error {{'pdr' declared as a member pointer to a reference}}
diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp
index 8a217b3..247e91b 100644
--- a/test/SemaCXX/nested-name-spec.cpp
+++ b/test/SemaCXX/nested-name-spec.cpp
@@ -13,8 +13,9 @@ namespace A {
}
A:: ; // expected-error {{expected unqualified-id}}
-::A::ax::undef ex3; // expected-error {{no member named}}
-A::undef1::undef2 ex4; // expected-error {{no member named 'undef1'}}
+// FIXME: redundant errors
+::A::ax::undef ex3; // expected-error {{no member named}} expected-error {{unknown type name}}
+A::undef1::undef2 ex4; // expected-error {{no member named 'undef1'}} expected-error {{unknown type name}}
int A::C::Ag1() { return 0; }
diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp
index acd4a23..68323d8 100644
--- a/test/SemaCXX/new-delete.cpp
+++ b/test/SemaCXX/new-delete.cpp
@@ -159,12 +159,10 @@ void loadEngineFor() {
}
template <class T> struct TBase {
- void* operator new(T size, int); // expected-error {{'operator new' cannot take a dependent type as first parameter; use size_t}}\
- // expected-error {{'operator new' takes type size_t}}
+ void* operator new(T size, int); // expected-error {{'operator new' cannot take a dependent type as first parameter; use size_t}}
};
-// FIXME: We should not try to instantiate operator new, since it is invalid.
-TBase<int> t1; // expected-note {{in instantiation of template class 'struct TBase<int>' requested here}}
+TBase<int> t1;
class X6 {
public:
diff --git a/test/SemaCXX/overload-call.cpp b/test/SemaCXX/overload-call.cpp
index e2a4fd8..77e0908 100644
--- a/test/SemaCXX/overload-call.cpp
+++ b/test/SemaCXX/overload-call.cpp
@@ -53,7 +53,7 @@ int* k(char*);
double* k(bool);
void test_k() {
- int* ip1 = k("foo");
+ int* ip1 = k("foo"); // expected-warning{{conversion from string literal to 'char *' is deprecated}}
double* dp1 = k(L"foo");
}
@@ -61,7 +61,7 @@ int* l(wchar_t*);
double* l(bool);
void test_l() {
- int* ip1 = l(L"foo");
+ int* ip1 = l(L"foo"); // expected-warning{{conversion from string literal to 'wchar_t *' is deprecated}}
double* dp1 = l("foo");
}
@@ -79,7 +79,7 @@ class E;
void test_n(E* e) {
char ca[7];
int* ip1 = n(ca);
- int* ip2 = n("foo");
+ int* ip2 = n("foo"); // expected-warning{{conversion from string literal to 'char *' is deprecated}}
float fa[7];
double* dp1 = n(fa);
@@ -359,3 +359,30 @@ namespace DerivedToBaseVsVoid {
int &ir = f(b);
}
}
+
+// PR 6398 + PR 6421
+namespace test4 {
+ class A;
+ class B {
+ static void foo(); // expected-note {{not viable}}
+ static void foo(int*); // expected-note {{not viable}}
+ static void foo(long*); // expected-note {{not viable}}
+
+ void bar(A *a) {
+ foo(a); // expected-error {{no matching function for call}}
+ }
+ };
+}
+
+namespace DerivedToBase {
+ struct A { };
+ struct B : A { };
+ struct C : B { };
+
+ int &f0(const A&);
+ float &f0(B);
+
+ void g() {
+ float &fr = f0(C());
+ }
+}
diff --git a/test/SemaCXX/pseudo-destructors.cpp b/test/SemaCXX/pseudo-destructors.cpp
index 15e37c5..472e5b4 100644
--- a/test/SemaCXX/pseudo-destructors.cpp
+++ b/test/SemaCXX/pseudo-destructors.cpp
@@ -5,21 +5,23 @@ enum Foo { F };
typedef Foo Bar;
typedef int Integer;
+typedef double Double;
void g();
namespace N {
typedef Foo Wibble;
+ typedef int OtherInteger;
}
-void f(A* a, Foo *f, int *i) {
+void f(A* a, Foo *f, int *i, double *d) {
a->~A();
a->A::~A();
a->~foo(); // expected-error{{identifier 'foo' in pseudo-destructor expression does not name a type}}
- // FIXME: the type printed below isn't wonderful
- a->~Bar(); // expected-error{{no member named}}
+ // FIXME: the diagnostic below isn't wonderful
+ a->~Bar(); // expected-error{{does not name a type}}
f->~Bar();
f->~Foo();
@@ -28,9 +30,17 @@ void f(A* a, Foo *f, int *i) {
g().~Bar(); // expected-error{{non-scalar}}
f->::~Bar();
- f->N::~Wibble();
+ f->N::~Wibble(); // FIXME: technically, Wibble isn't a class-name
f->::~Bar(17, 42); // expected-error{{cannot have any arguments}}
+
+ i->~Integer();
+ i->Integer::~Integer();
+ i->N::~OtherInteger();
+ i->N::OtherInteger::~OtherInteger();
+ i->N::OtherInteger::~Integer(); // expected-error{{'Integer' does not refer to a type name in pseudo-destructor expression; expected the name of type 'int'}}
+ i->N::~Integer(); // expected-error{{'Integer' does not refer to a type name in pseudo-destructor expression; expected the name of type 'int'}}
+ i->Integer::~Double(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('Double' (aka 'double')) in pseudo-destructor expression}}
}
typedef int Integer;
diff --git a/test/SemaCXX/statements.cpp b/test/SemaCXX/statements.cpp
index 3698258..852086e 100644
--- a/test/SemaCXX/statements.cpp
+++ b/test/SemaCXX/statements.cpp
@@ -1,5 +1,17 @@
-// RUN: %clang_cc1 %s -fsyntax-only -pedantic
+// RUN: %clang_cc1 %s -fsyntax-only -pedantic -verify
void foo() {
return foo();
}
+
+// PR6451 - C++ Jump checking
+struct X {
+ X();
+};
+
+void test2() {
+ goto later; // expected-error {{illegal goto into protected scope}}
+ X x; // expected-note {{jump bypasses variable initialization}}
+later:
+ ;
+}
diff --git a/test/SemaCXX/type-convert-construct.cpp b/test/SemaCXX/type-convert-construct.cpp
index d786a9a..8f92a03 100644
--- a/test/SemaCXX/type-convert-construct.cpp
+++ b/test/SemaCXX/type-convert-construct.cpp
@@ -11,7 +11,7 @@ void f() {
int *p;
bool v6 = T(0) == p;
char *str;
- str = "a string";
+ str = "a string"; // expected-warning{{conversion from string literal to 'char *' is deprecated}}
wchar_t *wstr;
- wstr = L"a wide string";
+ wstr = L"a wide string"; // expected-warning{{conversion from string literal to 'wchar_t *' is deprecated}}
}
diff --git a/test/SemaCXX/warn-unreachable.cpp b/test/SemaCXX/warn-unreachable.cpp
index a7ed91d..01b36de 100644
--- a/test/SemaCXX/warn-unreachable.cpp
+++ b/test/SemaCXX/warn-unreachable.cpp
@@ -52,8 +52,8 @@ void test4() {
int mem;
} s;
S &foor();
- halt(), foor()
- .mem; // expected-warning {{will never be executed}}
+ halt(), foor()// expected-warning {{will never be executed}}
+ .mem;
}
void test5() {
diff --git a/test/SemaObjC/category-1.m b/test/SemaObjC/category-1.m
index 33e4646..24324f8 100644
--- a/test/SemaObjC/category-1.m
+++ b/test/SemaObjC/category-1.m
@@ -73,3 +73,7 @@
@implementation MultipleCat_I // expected-warning {{incomplete implementation}}, expected-warning {{method definition for 'im0' not found}}
@end
+
+// <rdar://problem/7680391> - Handle nameless categories with no name that refer
+// to an undefined class
+@interface RDar7680391 () @end // expected-error{{cannot find interface declaration}}
diff --git a/test/SemaObjC/conditional-expr-7.m b/test/SemaObjC/conditional-expr-7.m
new file mode 100644
index 0000000..3ddf3d7
--- /dev/null
+++ b/test/SemaObjC/conditional-expr-7.m
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// radar 7682116
+
+@interface Super @end
+
+@interface NSArray : Super @end
+@interface NSSet : Super @end
+
+@protocol MyProtocol
+- (void)myMethod;
+@end
+
+@protocol MyProtocol2 <MyProtocol>
+- (void)myMethod2;
+@end
+
+@interface NSArray() <MyProtocol2>
+@end
+
+@interface NSSet() <MyProtocol>
+@end
+
+int main (int argc, const char * argv[]) {
+ NSArray *array = (void*)0;
+ NSSet *set = (void*)0;
+ id <MyProtocol> instance = (argc) ? array : set;
+ instance = (void*)0;
+ return 0;
+}
+
diff --git a/test/SemaObjC/duplicate-ivar-in-class-extension.m b/test/SemaObjC/duplicate-ivar-in-class-extension.m
new file mode 100644
index 0000000..b66736f
--- /dev/null
+++ b/test/SemaObjC/duplicate-ivar-in-class-extension.m
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-nonfragile-abi2 -verify %s
+
+@interface Root @end
+
+@interface SuperClass : Root
+{
+ int iSuper; // expected-note {{previous declaration is here}}
+}
+@end
+
+@interface SubClass : SuperClass {
+ int ivar; // expected-error {{duplicate member 'ivar'}}
+ int another_ivar; // expected-error {{duplicate member 'another_ivar'}}
+ int iSuper; // expected-error {{duplicate member 'iSuper'}}
+}
+@end
+
+@interface SuperClass () {
+ int ivar; // expected-note {{previous declaration is here}}
+}
+@end
+
+@interface Root () {
+ int another_ivar; // expected-note {{previous declaration is here}}
+}
+@end
+
+@implementation SubClass
+-(int) method {
+ return self->ivar; // would be ambiguous if the duplicate ivar were allowed
+}
+@end
diff --git a/test/SemaObjC/format-strings-objc.m b/test/SemaObjC/format-strings-objc.m
index 7abfe96..1fcc34f 100644
--- a/test/SemaObjC/format-strings-objc.m
+++ b/test/SemaObjC/format-strings-objc.m
@@ -50,3 +50,8 @@ void rdar_7068334() {
printf("%i ",test); // expected-warning{{conversion specifies type 'int' but the argument has type 'long long'}}
NSLog(@"%i ",test); // expected-warning{{conversion specifies type 'int' but the argument has type 'long long'}}
}
+
+// <rdar://problem/7697748>
+void rdar_7697748() {
+ NSLog(@"%@!"); // expected-warning{{more '%' conversions than data arguments}}
+}
diff --git a/test/SemaObjC/ivar-in-class-extension.m b/test/SemaObjC/ivar-in-class-extension.m
new file mode 100644
index 0000000..683a78f
--- /dev/null
+++ b/test/SemaObjC/ivar-in-class-extension.m
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-nonfragile-abi2 -verify %s
+
+@interface SomeClass @end
+
+int fn1(SomeClass *obj) {
+ obj->privateIvar = 1; // expected-error {{'SomeClass' does not have a member named 'privateIvar}}
+ return obj->publicIvar; // expected-error {{'SomeClass' does not have a member named 'publicIvar'}}
+}
+
+@interface SomeClass () {
+// @private by default
+ int privateIvar;
+@public
+ int publicIvar;
+}
+@end
+
+int fn2(SomeClass *obj) {
+ obj->publicIvar = 1;
+ return obj->publicIvar // ok
+ + obj->privateIvar; // expected-error {{instance variable 'privateIvar' is private}}
+}
+
+@implementation SomeClass
+
+int fn3(SomeClass *obj) {
+ obj->privateIvar = 2;
+ return obj->publicIvar // ok
+ + obj->privateIvar; // ok
+ }
+@end
+
+@interface SomeClass (Category)
+ { // expected-error {{ivar may be placed in a class extension}}
+ int categoryIvar;
+ }
+@end
+
+@interface SomeClass (Category1)
+ { // expected-error {{ivar may be placed in a class extension}}
+ }
+@end
diff --git a/test/SemaObjC/ivar-in-implementations.m b/test/SemaObjC/ivar-in-implementations.m
new file mode 100644
index 0000000..32d3c35
--- /dev/null
+++ b/test/SemaObjC/ivar-in-implementations.m
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-nonfragile-abi2 -verify %s
+
+@interface Super @end
+
+@interface INTFSTANDALONE : Super
+{
+ id IVAR; // expected-note {{previous definition is here}}
+}
+
+@end
+
+@implementation INTFSTANDALONE : Super // expected-warning {{class implementation may not have super class}}
+{
+@private
+ id IVAR1;
+@protected
+ id IVAR2; // expected-error {{only private ivars may be declared in implementation}}
+@private
+ id IVAR3;
+ int IVAR; // expected-error {{instance variable is already declared}}
+}
+@end
diff --git a/test/SemaObjC/method-warn-unused-attribute.m b/test/SemaObjC/method-warn-unused-attribute.m
new file mode 100644
index 0000000..d9dcf99
--- /dev/null
+++ b/test/SemaObjC/method-warn-unused-attribute.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused-value -verify %s
+
+@interface INTF
+// Currently this is rejected by both GCC and Clang (and Clang was crashing on it).
+- (id) foo __attribute__((warn_unused_result)); // expected-warning{{warning: 'warn_unused_result' attribute only applies to function types}}
+@end
+
+
diff --git a/test/SemaObjC/property-and-class-extension.m b/test/SemaObjC/property-and-class-extension.m
new file mode 100644
index 0000000..51bf8de
--- /dev/null
+++ b/test/SemaObjC/property-and-class-extension.m
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-nonfragile-abi2 -verify %s
+
+/**
+When processing @synthesize, treat ivars in a class extension the same as ivars in the class @interface,
+and treat ivars in a superclass extension the same as ivars in the superclass @interface.
+In particular, when searching for an ivar to back an @synthesize, do look at ivars in the class's own class
+extension but ignore any ivars in superclass class extensions.
+*/
+
+@interface Super {
+ int ISA;
+}
+@end
+
+@interface Super() {
+ int Property; // expected-note {{previously declared 'Property' here}}
+}
+@end
+
+@interface SomeClass : Super {
+ int interfaceIvar1;
+ int interfaceIvar2;
+}
+@property int Property;
+@property int Property1;
+@end
+
+@interface SomeClass () {
+ int Property1;
+}
+@end
+
+@implementation SomeClass
+@synthesize Property; // expected-error {{property 'Property' attempting to use ivar 'Property' declared in super class 'Super'}}
+@synthesize Property1; // OK
+@end
diff --git a/test/SemaObjC/property-user-setter.m b/test/SemaObjC/property-user-setter.m
index babccee..9479bc6 100644
--- a/test/SemaObjC/property-user-setter.m
+++ b/test/SemaObjC/property-user-setter.m
@@ -70,7 +70,7 @@ static int g_val;
{
int setterOnly;
}
-- (void) setSetterOnly:(int)value;
+- (void) setSetterOnly:(int)value; // expected-note {{or because setter is declared here, but no getter method 'setterOnly' is found}}
@end
@implementation Subclass
@@ -82,7 +82,7 @@ static int g_val;
@interface C {}
// - (int)Foo;
-- (void)setFoo:(int)value;
+- (void)setFoo:(int)value; // expected-note 2 {{or because setter is declared here, but no getter method 'Foo' is found}}
@end
void g(int);
diff --git a/test/SemaObjC/stand-alone-implementation.m b/test/SemaObjC/stand-alone-implementation.m
new file mode 100644
index 0000000..c33b66a
--- /dev/null
+++ b/test/SemaObjC/stand-alone-implementation.m
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// radar 7547942
+// Allow injection of ivars into implementation's implicit class.
+
+@implementation INTFSTANDALONE // expected-warning {{cannot find interface declaration for 'INTFSTANDALONE'}}
+{
+ id IVAR1;
+ id IVAR2;
+}
+- (id) Meth { return IVAR1; }
+@end
+
diff --git a/test/SemaObjC/unused.m b/test/SemaObjC/unused.m
index 7fdb801..e994188 100644
--- a/test/SemaObjC/unused.m
+++ b/test/SemaObjC/unused.m
@@ -7,19 +7,14 @@ int printf(const char *, ...);
@end
@implementation Greeter
-+ (void) hello {
- printf("Hello, World!\n");
-}
++ (void) hello { printf("Hello, World!\n"); }
@end
-
int test1(void) {
[Greeter hello];
return 0;
}
-
-
@interface NSObject @end
@interface NSString : NSObject
- (int)length;
@@ -29,10 +24,6 @@ void test2() {
@"pointless example call for test purposes".length; // expected-warning {{property access result unused - getters should not have side effects}}
}
-
-
-
-
@interface foo
- (int)meth: (int)x: (int)y: (int)z ;
@end
@@ -42,3 +33,13 @@ void test2() {
(int)y: // expected-warning{{unused}}
(int) __attribute__((unused))z { return x; }
@end
+
+//===------------------------------------------------------------------------===
+// The next test shows how clang accepted attribute((unused)) on ObjC
+// instance variables, which GCC does not.
+//===------------------------------------------------------------------------===
+
+@interface TestUnusedIvar {
+ id x __attribute__((unused)); // no-warning
+}
+@end
diff --git a/test/SemaObjCXX/message.mm b/test/SemaObjCXX/message.mm
new file mode 100644
index 0000000..93a600a
--- /dev/null
+++ b/test/SemaObjCXX/message.mm
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+@interface I1
+- (void)method;
+@end
+
+@implementation I1
+- (void)method {
+ struct x { };
+ [x method]; // expected-error{{invalid receiver to message expression}}
+}
+@end
+
+typedef struct { int x; } ivar;
+
+@interface I2 {
+ id ivar;
+}
+- (void)method;
++ (void)method;
+@end
+
+@implementation I2
+- (void)method {
+ [ivar method];
+}
++ (void)method {
+ [ivar method]; // expected-error{{invalid receiver to message expression}}
+}
+@end
diff --git a/test/SemaObjCXX/vla.mm b/test/SemaObjCXX/vla.mm
new file mode 100644
index 0000000..9c6fc54
--- /dev/null
+++ b/test/SemaObjCXX/vla.mm
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+@interface Data
+- (unsigned)length;
+- (void)getData:(void*)buffer;
+@end
+
+void test(Data *d) {
+ char buffer[[d length]]; // expected-error{{variable length arrays are not permitted in C++}}
+ [d getData:buffer];
+}
+
diff --git a/test/SemaTemplate/dependent-base-classes.cpp b/test/SemaTemplate/dependent-base-classes.cpp
index 80d20b0..08d4de5 100644
--- a/test/SemaTemplate/dependent-base-classes.cpp
+++ b/test/SemaTemplate/dependent-base-classes.cpp
@@ -57,7 +57,6 @@ namespace PR6031 {
int foo() {
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{{expected an identifier or template-id after '::'}} \
// FIXME: expected-error{{unqualified-id}}
return NoDepBase::a; // expected-error{{no member named 'a' in 'struct PR6031::NoDepBase'}}
}
@@ -110,3 +109,27 @@ namespace PR6081 {
}
};
}
+
+namespace PR6413 {
+ template <typename T> class Base_A { };
+
+ class Base_B { };
+
+ template <typename T>
+ class Derived
+ : public virtual Base_A<T>
+ , public virtual Base_B
+ { };
+}
+
+namespace PR5812 {
+ template <class T> struct Base {
+ Base* p;
+ };
+
+ template <class T> struct Derived: public Base<T> {
+ typename Derived::Base* p; // meaning Derived::Base<T>
+ };
+
+ Derived<int> di;
+}
diff --git a/test/SemaTemplate/destructor-template.cpp b/test/SemaTemplate/destructor-template.cpp
index b5ad967..83b1bee 100644
--- a/test/SemaTemplate/destructor-template.cpp
+++ b/test/SemaTemplate/destructor-template.cpp
@@ -17,3 +17,18 @@ void destroy_me(T me) {
}
template void destroy_me(Incomplete*);
+
+namespace PR6152 {
+ template<typename T> struct X { void f(); };
+ template<typename T> struct Y { };
+ template<typename T>
+ void X<T>::f() {
+ Y<T> *y;
+ y->template Y<T>::~Y();
+ y->template Y<T>::~Y<T>();
+ y->~Y();
+ }
+
+ template struct X<int>;
+}
+
diff --git a/test/SemaTemplate/explicit-specialization-member.cpp b/test/SemaTemplate/explicit-specialization-member.cpp
index 06dd382..cb0a39a 100644
--- a/test/SemaTemplate/explicit-specialization-member.cpp
+++ b/test/SemaTemplate/explicit-specialization-member.cpp
@@ -9,3 +9,15 @@ struct X0 {
template<> void X0<char>::f0(char);
template<> void X0<char>::f1(type);
+
+namespace PR6161 {
+ template<typename _CharT>
+ class numpunct : public locale::facet // expected-error{{use of undeclared identifier 'locale'}} \
+ // expected-error{{expected class name}} \
+ // expected-note{{attempt to specialize declaration here}}
+ {
+ static locale::id id; // expected-error{{use of undeclared identifier}} FIXME: expected-error {{unknown type name}}
+ };
+ numpunct<char>::~numpunct(); // expected-error{{template specialization requires 'template<>'}} \
+ // expected-error{{specialization of member 'PR6161::numpunct<char>::~numpunct' does not specialize an instantiated member}}
+}
diff --git a/test/SemaTemplate/instantiate-complete.cpp b/test/SemaTemplate/instantiate-complete.cpp
index 183fefa..0ae13b9 100644
--- a/test/SemaTemplate/instantiate-complete.cpp
+++ b/test/SemaTemplate/instantiate-complete.cpp
@@ -66,3 +66,20 @@ struct X3 {
void enum_constructors(X1<float> &x1) {
X3<X1<float> > x3 = x1;
}
+
+namespace PR6376 {
+ template<typename T, typename U> struct W { };
+
+ template<typename T>
+ struct X {
+ template<typename U>
+ struct apply {
+ typedef W<T, U> type;
+ };
+ };
+
+ template<typename T, typename U>
+ struct Y : public X<T>::template apply<U>::type { };
+
+ template struct Y<int, float>;
+}
diff --git a/test/SemaTemplate/instantiate-enum.cpp b/test/SemaTemplate/instantiate-enum.cpp
index 6f9aa4b..5353a92 100644
--- a/test/SemaTemplate/instantiate-enum.cpp
+++ b/test/SemaTemplate/instantiate-enum.cpp
@@ -9,3 +9,19 @@ struct adder {
};
int array1[adder<long, 3, 4>::value == 7? 1 : -1];
+
+namespace PR6375 {
+ template<typename T>
+ void f() {
+ enum Enum
+ {
+ enumerator1 = 0xFFFFFFF,
+ enumerator2 = enumerator1 - 1
+ };
+
+ int xb1 = enumerator1;
+ int xe1 = enumerator2;
+ }
+
+ template void f<int>();
+}
diff --git a/test/SemaTemplate/instantiate-expr-1.cpp b/test/SemaTemplate/instantiate-expr-1.cpp
index d1b05f6..37145b6 100644
--- a/test/SemaTemplate/instantiate-expr-1.cpp
+++ b/test/SemaTemplate/instantiate-expr-1.cpp
@@ -137,3 +137,36 @@ void test_asm() {
int b;
test_asm(b); // expected-note {{in instantiation of function template specialization 'test_asm<int>' requested here}}
}
+
+namespace PR6424 {
+ template<int I> struct X {
+ X() {
+ int *ip = I; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
+ }
+ };
+
+ template<int> struct Y {
+ typedef X<7> X7;
+
+ void f() { X7(); } // expected-note{{instantiation}}
+ };
+
+ template void Y<3>::f();
+
+ template<int I>
+ struct X2 {
+ void *operator new(__SIZE_TYPE__) {
+ int *ip = I; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
+ return ip;
+ }
+ };
+
+ template<int> struct Y2 {
+ typedef X2<7> X;
+ void f() {
+ new X(); // expected-note{{instantiation of}}
+ }
+ };
+
+ template void Y2<3>::f();
+}
diff --git a/test/SemaTemplate/instantiate-function-1.cpp b/test/SemaTemplate/instantiate-function-1.cpp
index 543b3cc..144c630 100644
--- a/test/SemaTemplate/instantiate-function-1.cpp
+++ b/test/SemaTemplate/instantiate-function-1.cpp
@@ -177,9 +177,11 @@ template<typename T> struct IndirectGoto0 {
goto *x; // expected-error{{incompatible}}
prior:
- T prior_label = &&prior;
+ T prior_label;
+ prior_label = &&prior;
- T later_label = &&later;
+ T later_label;
+ later_label = &&later;
later:
(void)(1+1);
diff --git a/test/SemaTemplate/instantiate-init.cpp b/test/SemaTemplate/instantiate-init.cpp
index 8a10a87..16ecc47 100644
--- a/test/SemaTemplate/instantiate-init.cpp
+++ b/test/SemaTemplate/instantiate-init.cpp
@@ -26,3 +26,14 @@ void test_f1(X0 *x0, int *ip, float *fp, double *dp) {
f1(x0, ip, dp); // expected-note{{instantiation}}
}
+namespace PR6457 {
+ template <typename T> struct X { explicit X(T* p = 0) { }; };
+ template <typename T> struct Y { Y(int, const T& x); };
+ struct A { };
+ template <typename T>
+ struct B {
+ B() : y(0, X<A>()) { }
+ Y<X<A> > y;
+ };
+ B<int> b;
+}
diff --git a/test/SemaTemplate/instantiate-invalid.cpp b/test/SemaTemplate/instantiate-invalid.cpp
new file mode 100644
index 0000000..b8a5901
--- /dev/null
+++ b/test/SemaTemplate/instantiate-invalid.cpp
@@ -0,0 +1,52 @@
+// RUN: not %clang_cc1 -fsyntax-only %s
+namespace PR6375 {
+ template<class Conv> class rasterizer_sl_clip Conv::xi(x2), Conv::yi(y2));
+namespace agg
+{
+ template<class Clip=rasterizer_sl_clip_int> class rasterizer_scanline_aa
+ {
+ template<class Scanline> bool sweep_scanline(Scanline& sl)
+ {
+ unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
+ while(num_cells) { }
+ }
+ }
+ class scanline_u8 {}
+ template<class PixelFormat> class renderer_base { }
+}
+ template<class Rasterizer, class Scanline, class BaseRenderer, class ColorT>
+ void render_scanlines_aa_solid(Rasterizer& ras, Scanline& sl, BaseRenderer& ren, const ColorT& color)
+ {
+ while(ras.sweep_scanline(sl))
+ {
+ }
+ };
+namespace agg
+{
+ struct rgba8
+ {
+ };
+ template<class Rasterizer, class Scanline, class Renderer, class Ctrl>
+ void render_ctrl(Rasterizer& ras, Scanline& sl, Renderer& r, Ctrl& c)
+ {
+ unsigned i;
+ render_scanlines_aa_solid(ras, sl, r, c.color(i));
+ }
+ template<class ColorT> class rbox_ctrl : public rbox_ctrl_impl
+ {
+ const ColorT& color(unsigned i) const { return *m_colors[i]; }
+ }
+class the_application : public agg::platform_support
+{
+ agg::rbox_ctrl<agg::rgba8> m_polygons;
+ virtual void on_init()
+ {
+ typedef agg::renderer_base<pixfmt_type> base_ren_type;
+ base_ren_type ren_base(pf);
+ agg::scanline_u8 sl;
+ agg::rasterizer_scanline_aa<> ras;
+ agg::render_ctrl(ras, sl, ren_base, m_polygons);
+ }
+};
+}
+}
diff --git a/test/SemaTemplate/instantiate-static-var.cpp b/test/SemaTemplate/instantiate-static-var.cpp
index 789fe3d..fda2b9ea 100644
--- a/test/SemaTemplate/instantiate-static-var.cpp
+++ b/test/SemaTemplate/instantiate-static-var.cpp
@@ -92,3 +92,26 @@ struct SizeOf {
void MyTest3() {
Y3().Foo(X3<SizeOf<char>::value>());
}
+
+namespace PR6449 {
+ template<typename T>
+ struct X0 {
+ static const bool var = false;
+ };
+
+ template<typename T>
+ const bool X0<T>::var;
+
+ template<typename T>
+ struct X1 : public X0<T> {
+ static const bool var = false;
+ };
+
+ template<typename T>
+ const bool X1<T>::var;
+
+ template class X0<char>;
+ template class X1<char>;
+
+}
+
diff --git a/test/SemaTemplate/member-access-expr.cpp b/test/SemaTemplate/member-access-expr.cpp
index 116e837..24db791 100644
--- a/test/SemaTemplate/member-access-expr.cpp
+++ b/test/SemaTemplate/member-access-expr.cpp
@@ -63,11 +63,13 @@ void test_convert(X2 x2) {
template<typename T>
void destruct(T* ptr) {
ptr->~T();
+ ptr->T::~T();
}
template<typename T>
void destruct_intptr(int *ip) {
ip->~T();
+ ip->T::~T();
}
void test_destruct(X2 *x2p, int *ip) {
diff --git a/test/SemaTemplate/nested-name-spec-template.cpp b/test/SemaTemplate/nested-name-spec-template.cpp
index 704b8cf..1691db7 100644
--- a/test/SemaTemplate/nested-name-spec-template.cpp
+++ b/test/SemaTemplate/nested-name-spec-template.cpp
@@ -49,6 +49,5 @@ struct ::N::A<int>::X {
template<typename T>
struct TestA {
typedef typename N::template B<T>::type type; // expected-error{{'B' following the 'template' keyword does not refer to a template}} \
- // expected-error{{identifier or template-id}} \
// expected-error{{expected member name}}
};
diff --git a/test/SemaTemplate/temp_arg.cpp b/test/SemaTemplate/temp_arg.cpp
index 3c9fcb5..80bbda7 100644
--- a/test/SemaTemplate/temp_arg.cpp
+++ b/test/SemaTemplate/temp_arg.cpp
@@ -10,3 +10,10 @@ A<int, 0, X> * a1;
A<float, 1, X, double> *a2; // expected-error{{too many template arguments for class template 'A'}}
A<float, 1> *a3; // expected-error{{too few template arguments for class template 'A'}}
+
+namespace test0 {
+ template <class t> class foo {};
+ template <class t> class bar {
+ bar(::test0::foo<tee> *ptr) {} // FIXME(redundant): expected-error 2 {{use of undeclared identifier 'tee'}}
+ };
+}
diff --git a/test/SemaTemplate/template-decl-fail.cpp b/test/SemaTemplate/template-decl-fail.cpp
index a298c6d..eca0f58 100644
--- a/test/SemaTemplate/template-decl-fail.cpp
+++ b/test/SemaTemplate/template-decl-fail.cpp
@@ -1,3 +1,8 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
template<typename T> typedef T X; // expected-error{{typedef cannot be a template}}
+
+template<typename T>
+enum t0 { A = T::x }; // expected-error{{enumeration cannot be a template}} \
+ // expected-error{{declaration does not declare anything}}
+
diff --git a/test/SemaTemplate/virtual-member-functions.cpp b/test/SemaTemplate/virtual-member-functions.cpp
index db24313..58ac08c 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();
+ x.anchor(); // expected-note{{in instantiation of member function 'PR5557::A<int>::anchor' requested here}}
}
template<typename T>
@@ -36,10 +36,10 @@ struct Base {
template<typename T>
struct Derived : Base<T> {
- virtual void foo() { }
+ virtual void foo() { } // expected-note {{in instantiation of member function 'Base<int>::~Base' requested here}}
};
-template struct Derived<int>; // expected-note{{instantiation}}
+template struct Derived<int>;
template<typename T>
struct HasOutOfLineKey {
@@ -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;
+HasOutOfLineKey<int> out_of_line; // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::HasOutOfLineKey' requested here}}
diff --git a/test/lit.cfg b/test/lit.cfg
index 4d7a17a..beb8ae0 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -123,12 +123,15 @@ config.clang = inferClang(config.environment['PATH'])
if not lit.quiet:
lit.note('using clang: %r' % config.clang)
config.substitutions.append( ('%clang_cc1', config.clang + ' -cc1') )
+config.substitutions.append( ('%clangxx', ' ' + config.clang + ' -ccc-cxx'))
config.substitutions.append( ('%clang', ' ' + config.clang + ' ') )
# FIXME: Find nicer way to prohibit this.
config.substitutions.append(
(' clang ', """*** Do not use 'clang' in tests, use '%clang'. ***""") )
config.substitutions.append(
+ (' clang++ ', """*** Do not use 'clang++' in tests, use '%clangxx'. ***"""))
+config.substitutions.append(
(' clang-cc ',
"""*** Do not use 'clang-cc' in tests, use '%clang_cc1'. ***""") )
config.substitutions.append(
OpenPOWER on IntegriCloud