diff options
author | Joao Matos <ripzonetriton@gmail.com> | 2012-08-31 18:45:21 +0000 |
---|---|---|
committer | Joao Matos <ripzonetriton@gmail.com> | 2012-08-31 18:45:21 +0000 |
commit | 6666ed4ed2e2bc13da5ac5d0a4947019137d45be (patch) | |
tree | aa69fbfff54188e6a8e772240a87e40e6b927b76 | |
parent | a89f719ad3a7134e3eec7c9e03aa0e22031c0de9 (diff) |
Improved MSVC __interface support by adding first class support for it, instead of aliasing to "struct" which had some incorrect behaviour. Patch by David Robins.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163013 91177308-0d34-0410-b5e6-96231b3b80d8
30 files changed, 1414 insertions, 1247 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index 1347f6c167..9ed0570cf6 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -4962,13 +4962,14 @@ typedef enum { CXIdxEntity_CXXStaticVariable = 19, CXIdxEntity_CXXStaticMethod = 20, CXIdxEntity_CXXInstanceMethod = 21, - CXIdxEntity_CXXConstructor = 22, - CXIdxEntity_CXXDestructor = 23, - CXIdxEntity_CXXConversionFunction = 24, - CXIdxEntity_CXXTypeAlias = 25 - -} CXIdxEntityKind; - + CXIdxEntity_CXXConstructor = 22,
+ CXIdxEntity_CXXDestructor = 23,
+ CXIdxEntity_CXXConversionFunction = 24,
+ CXIdxEntity_CXXTypeAlias = 25,
+ CXIdxEntity_CXXInterface = 26
+
+} CXIdxEntityKind;
+
typedef enum { CXIdxEntityLang_None = 0, CXIdxEntityLang_C = 1, diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h index 6cce88868d..ea307bf307 100644 --- a/include/clang/AST/CanonicalType.h +++ b/include/clang/AST/CanonicalType.h @@ -276,6 +276,7 @@ public: LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isInterfaceType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureOrClassType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType) diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index e9f25b368a..5dcc104874 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -2448,7 +2448,7 @@ public: private: // FIXME: This can be packed into the bitfields in Decl. /// TagDeclKind - The TagKind enum. - unsigned TagDeclKind : 2; + unsigned TagDeclKind : 3; /// IsCompleteDefinition - True if this is a definition ("struct foo /// {};"), false if it is a declaration ("struct foo;"). It is not @@ -2625,6 +2625,7 @@ public: void setTagKind(TagKind TK) { TagDeclKind = TK; } bool isStruct() const { return getTagKind() == TTK_Struct; } + bool isInterface() const { return getTagKind() == TTK_Interface; } bool isClass() const { return getTagKind() == TTK_Class; } bool isUnion() const { return getTagKind() == TTK_Union; } bool isEnum() const { return getTagKind() == TTK_Enum; } diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 65a0dab5c2..676d0f9e9e 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -1553,13 +1553,15 @@ public: bool isVolatile() { return getType()->castAs<FunctionType>()->isVolatile(); } bool isVirtual() const { - CXXMethodDecl *CD = - cast<CXXMethodDecl>(const_cast<CXXMethodDecl*>(this)->getCanonicalDecl()); - - if (CD->isVirtualAsWritten()) - return true; - - return (CD->begin_overridden_methods() != CD->end_overridden_methods()); + CXXMethodDecl *CD =
+ cast<CXXMethodDecl>(const_cast<CXXMethodDecl*>(this)->getCanonicalDecl());
+
+ // Methods declared in interfaces are automatically (pure) virtual
+ if (CD->isVirtualAsWritten() ||
+ CD->getParent()->getTagKind() == TTK_Interface)
+ return true;
+
+ return (CD->begin_overridden_methods() != CD->end_overridden_methods());
} /// \brief Determine whether this is a usual deallocation function diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 6564b66548..8630011929 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -1512,6 +1512,7 @@ public: bool isRecordType() const; bool isClassType() const; bool isStructureType() const; + bool isInterfaceType() const; bool isStructureOrClassType() const; bool isUnionType() const; bool isComplexIntegerType() const; // GCC _Complex integer type. @@ -3796,6 +3797,8 @@ public: enum TagTypeKind { /// \brief The "struct" keyword. TTK_Struct, + /// \brief The "__interface" keyword. + TTK_Interface, /// \brief The "union" keyword. TTK_Union, /// \brief The "class" keyword. @@ -3809,6 +3812,8 @@ enum TagTypeKind { enum ElaboratedTypeKeyword { /// \brief The "struct" keyword introduces the elaborated-type-specifier. ETK_Struct, + /// \brief The "__interface" keyword introduces the elaborated-type-specifier. + ETK_Interface, /// \brief The "union" keyword introduces the elaborated-type-specifier. ETK_Union, /// \brief The "class" keyword introduces the elaborated-type-specifier. diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td index 9cfe5efae2..c64060081f 100644 --- a/include/clang/Basic/DiagnosticASTKinds.td +++ b/include/clang/Basic/DiagnosticASTKinds.td @@ -134,13 +134,13 @@ def note_odr_defined_here : Note<"also defined here">; def err_odr_function_type_inconsistent : Error< "external function %0 declared with incompatible types in different " "translation units (%1 vs. %2)">; -def warn_odr_tag_type_inconsistent : Warning< - "type %0 has incompatible definitions in different translation units">; -def note_odr_tag_kind_here: Note< - "%0 is a %select{struct|union|class|enum}1 here">; -def note_odr_field : Note<"field %0 has type %1 here">; -def note_odr_missing_field : Note<"no corresponding field here">; -def note_odr_bit_field : Note<"bit-field %0 with type %1 and length %2 here">; +def warn_odr_tag_type_inconsistent : Warning<
+ "type %0 has incompatible definitions in different translation units">;
+def note_odr_tag_kind_here: Note<
+ "%0 is a %select{struct|interface|union|class|enum}1 here">;
+def note_odr_field : Note<"field %0 has type %1 here">;
+def note_odr_missing_field : Note<"no corresponding field here">;
+def note_odr_bit_field : Note<"bit-field %0 with type %1 and length %2 here">;
def note_odr_not_bit_field : Note<"field %0 is not a bit-field">; def note_odr_base : Note<"class has base type %0">; def note_odr_virtual_base : Note< diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index f88a9dd4a6..53d58c085c 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -573,13 +573,13 @@ def err_expected_semi_after_tagdecl : Error< def err_typename_refers_to_non_type_template : Error< "typename specifier refers to a non-template">; def err_expected_type_name_after_typename : Error< - "expected an identifier or template-id after '::'">; -def err_explicit_spec_non_template : Error< - "explicit %select{specialization|instantiation}0 of non-template " - "%select{class|struct|union}1 %2">; - -def err_default_template_template_parameter_not_template : Error< - "default template argument for a template template parameter must be a class " + "expected an identifier or template-id after '::'">;
+def err_explicit_spec_non_template : Error<
+ "explicit %select{specialization|instantiation}0 of non-template "
+ "%select{class|struct|union|interface}1 %2">;
+
+def err_default_template_template_parameter_not_template : Error<
+ "default template argument for a template template parameter must be a class "
"template">; def err_ctor_init_missing_comma : Error< diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 05877705af..ead6159e5b 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -793,16 +793,17 @@ def err_friend_is_member : Error< "friends cannot be members of the declaring class">; def warn_cxx98_compat_friend_is_member : Warning< "friend declaration naming a member of the declaring class is incompatible " - "with C++98">, InGroup<CXX98Compat>, DefaultIgnore; -def ext_unelaborated_friend_type : ExtWarn< - "unelaborated friend declaration is a C++11 extension; specify " - "'%select{struct|union|class|enum}0' to befriend %1">, InGroup<CXX11>; -def warn_cxx98_compat_unelaborated_friend_type : Warning< - "befriending %1 without '%select{struct|union|class|enum}0' keyword is " - "incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; -def err_qualified_friend_not_found : Error< - "no function named %0 with type %1 was found in the specified scope">; -def err_introducing_special_friend : Error< + "with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
+def ext_unelaborated_friend_type : ExtWarn<
+ "unelaborated friend declaration is a C++11 extension; specify "
+ "'%select{struct|interface|union|class|enum}0' to befriend %1">,
+ InGroup<CXX11>;
+def warn_cxx98_compat_unelaborated_friend_type : Warning<
+ "befriending %1 without '%select{struct|interface|union|class|enum}0' "
+ "keyword is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore;
+def err_qualified_friend_not_found : Error<
+ "no function named %0 with type %1 was found in the specified scope">;
+def err_introducing_special_friend : Error<
"must use a qualified name when declaring a %select{constructor|" "destructor|conversion operator}0 as a friend">; def err_tagless_friend_type_template : Error< @@ -1114,14 +1115,14 @@ def err_ref_qualifier_constructor : Error< def err_constructor_return_type : Error< "constructor cannot have a return type">; def err_constructor_redeclared : Error<"constructor cannot be redeclared">; -def err_constructor_byvalue_arg : Error< - "copy constructor must pass its first argument by reference">; -def warn_no_constructor_for_refconst : Warning< - "%select{struct|union|class|enum}0 %1 does not declare any constructor to " - "initialize its non-modifiable members">; -def note_refconst_member_not_initialized : Note< - "%select{const|reference}0 member %1 will never be initialized">; -def ext_ms_explicit_constructor_call : ExtWarn< +def err_constructor_byvalue_arg : Error<
+ "copy constructor must pass its first argument by reference">;
+def warn_no_constructor_for_refconst : Warning<
+ "%select{struct|interface|union|class|enum}0 %1 does not declare any "
+ "constructor to initialize its non-modifiable members">;
+def note_refconst_member_not_initialized : Note<
+ "%select{const|reference}0 member %1 will never be initialized">;
+def ext_ms_explicit_constructor_call : ExtWarn<
"explicit constructor calls are a Microsoft extension">, InGroup<Microsoft>; // C++ destructors @@ -1308,15 +1309,16 @@ def err_auto_variable_cannot_appear_in_own_initializer : Error< def err_illegal_decl_array_of_auto : Error< "'%0' declared as array of %1">; def err_new_array_of_auto : Error< - "cannot allocate array of 'auto'">; -def err_auto_not_allowed : Error< - "'auto' not allowed %select{in function prototype|in non-static struct member" - "|in non-static union member|in non-static class member|in exception declaration" - "|in template parameter|in block literal|in template argument" - "|in typedef|in type alias|in function return type|here}0">; -def err_auto_var_requires_init : Error< - "declaration of variable %0 with type %1 requires an initializer">; -def err_auto_new_requires_ctor_arg : Error< + "cannot allocate array of 'auto'">;
+def err_auto_not_allowed : Error<
+ "'auto' not allowed %select{in function prototype|in non-static struct member"
+ "|in non-static union member|in non-static class member|in interface member"
+ "|in exception declaration|in template parameter|in block literal"
+ "|in template argument|in typedef|in type alias|in function return type"
+ "|here}0">;
+def err_auto_var_requires_init : Error<
+ "declaration of variable %0 with type %1 requires an initializer">;
+def err_auto_new_requires_ctor_arg : Error<
"new expression for type %0 requires a constructor argument">; def err_auto_new_requires_parens : Error< "new expression for type %0 cannot use list-initialization">; @@ -1436,13 +1438,13 @@ def warn_cxx98_compat_constexpr : Warning< "'constexpr' specifier is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; def err_invalid_constexpr : Error< - "%select{function parameter|typedef|non-static data member}0 " - "cannot be constexpr">; -def err_constexpr_tag : Error< - "%select{class|struct|union|enum}0 cannot be marked constexpr">; -def err_constexpr_dtor : Error<"destructor cannot be marked constexpr">; -def err_constexpr_no_declarators : Error< - "constexpr can only be used in variable and function declarations">; + "%select{function parameter|typedef|non-static data member}0 "
+ "cannot be constexpr">;
+def err_constexpr_tag : Error<
+ "%select{class|struct|interface|union|enum}0 cannot be marked constexpr">;
+def err_constexpr_dtor : Error<"destructor cannot be marked constexpr">;
+def err_constexpr_no_declarators : Error<
+ "constexpr can only be used in variable and function declarations">;
def err_invalid_constexpr_var_decl : Error< "constexpr variable declaration must be a definition">; def err_constexpr_static_mem_var_requires_init : Error< @@ -1454,17 +1456,18 @@ def err_constexpr_var_requires_const_init : Error< def err_constexpr_redecl_mismatch : Error< "%select{non-constexpr declaration of %0 follows constexpr declaration" "|constexpr declaration of %0 follows non-constexpr declaration}1">; -def err_constexpr_virtual : Error<"virtual function cannot be constexpr">; -def err_constexpr_virtual_base : Error< - "constexpr %select{member function|constructor}0 not allowed in " - "%select{class|struct}1 with virtual base %plural{1:class|:classes}2">; -def note_non_literal_incomplete : Note< - "incomplete type %0 is not a literal type">; -def note_non_literal_virtual_base : Note<"%select{class|struct}0 with virtual " - "base %plural{1:class|:classes}1 is not a literal type">; -def note_constexpr_virtual_base_here : Note<"virtual base class declared here">; -def err_constexpr_non_literal_return : Error< - "constexpr function's return type %0 is not a literal type">; +def err_constexpr_virtual : Error<"virtual function cannot be constexpr">;
+def err_constexpr_virtual_base : Error<
+ "constexpr %select{member function|constructor}0 not allowed in "
+ "%select{struct|interface|class}1 with virtual base "
+ "%plural{1:class|:classes}2">;
+def note_non_literal_incomplete : Note<
+ "incomplete type %0 is not a literal type">;
+def note_non_literal_virtual_base : Note<"%select{struct|interface|class}0 "
+ "with virtual base %plural{1:class|:classes}1 is not a literal type">;
+def note_constexpr_virtual_base_here : Note<"virtual base class declared here">;
+def err_constexpr_non_literal_return : Error<
+ "constexpr function's return type %0 is not a literal type">;
def err_constexpr_non_literal_param : Error< "constexpr %select{function|constructor}1's %ordinal0 parameter type %2 is " "not a literal type">; @@ -1697,13 +1700,15 @@ def warn_unhandled_ms_attribute_ignored : Warning< "__declspec attribute %0 is not supported">, InGroup<IgnoredAttributes>; def warn_attribute_invalid_on_stmt : Warning< - "attribute %0 cannot be specified on a statement">, - InGroup<IgnoredAttributes>; -def warn_declspec_attribute_ignored : Warning< - "attribute %0 is ignored, place it after \"%select{class|struct|union|enum}1\" to apply attribute to type declaration">, InGroup<IgnoredAttributes>; -def warn_attribute_precede_definition : Warning< - "attribute declaration must precede definition">, - InGroup<IgnoredAttributes>; + "attribute %0 cannot be specified on a statement">,
+ InGroup<IgnoredAttributes>;
+def warn_declspec_attribute_ignored : Warning<
+ "attribute %0 is ignored, place it after "
+ "\"%select{class|struct|union|interface|enum}1\" to apply attribute to "
+ "type declaration">, InGroup<IgnoredAttributes>;
+def warn_attribute_precede_definition : Warning<
+ "attribute declaration must precede definition">,
+ InGroup<IgnoredAttributes>;
def warn_attribute_void_function_method : Warning< "attribute %0 cannot be applied to " "%select{functions|Objective-C method}1 without return value">, @@ -3178,30 +3183,31 @@ def err_redefinition_different_typedef : Error< def err_tag_reference_non_tag : Error< "elaborated type refers to %select{a non-tag type|a typedef|a type alias|a template|a type alias template}0">; def err_tag_reference_conflict : Error< - "implicit declaration introduced by elaborated type conflicts with " - "%select{a declaration|a typedef|a type alias|a template}0 of the same name">; -def err_dependent_tag_decl : Error< - "%select{declaration|definition}0 of %select{struct|union|class|enum}1 " - "in a dependent scope">; -def err_tag_definition_of_typedef : Error< - "definition of type %0 conflicts with %select{typedef|type alias}1 of the same name">; -def err_conflicting_types : Error<"conflicting types for %0">; + "implicit declaration introduced by elaborated type conflicts with "
+ "%select{a declaration|a typedef|a type alias|a template}0 of the same name">;
+def err_dependent_tag_decl : Error<
+ "%select{declaration|definition}0 of "
+ "%select{struct|interface|union|class|enum}1 in a dependent scope">;
+def err_tag_definition_of_typedef : Error<
+ "definition of type %0 conflicts with %select{typedef|type alias}1 of the same name">;
+def err_conflicting_types : Error<"conflicting types for %0">;
def err_nested_redefinition : Error<"nested redefinition of %0">; -def err_use_with_wrong_tag : Error< - "use of %0 with tag type that does not match previous declaration">; -def warn_struct_class_tag_mismatch : Warning< - "%select{struct|class}0%select{| template}1 %2 was previously declared " - "as a %select{class|struct}0%select{| template}1">, - InGroup<MismatchedTags>, DefaultIgnore; -def warn_struct_class_previous_tag_mismatch : Warning< - "%2 defined as a %select{struct|class}0%select{| template}1 here but " - "previously declared as a %select{class|struct}0%select{| template}1">, - InGroup<MismatchedTags>, DefaultIgnore; -def note_struct_class_suggestion : Note< - "did you mean %select{struct|class}0 here?">; -def ext_forward_ref_enum : Extension< - "ISO C forbids forward references to 'enum' types">; -def err_forward_ref_enum : Error< +def err_use_with_wrong_tag : Error<
+ "use of %0 with tag type that does not match previous declaration">;
+def warn_struct_class_tag_mismatch : Warning<
+ "%select{struct|interface|class}0%select{| template}1 %2 was previously "
+ "declared as a %select{struct|interface|class}3%select{| template}1">,
+ InGroup<MismatchedTags>, DefaultIgnore;
+def warn_struct_class_previous_tag_mismatch : Warning<
+ "%2 defined as %select{a struct|an interface|a class}0%select{| template}1 "
+ "here but previously declared as "
+ "%select{a struct|an interface|a class}3%select{| template}1">,
+ InGroup<MismatchedTags>, DefaultIgnore;
+def note_struct_class_suggestion : Note<
+ "did you mean %select{struct|interface|class}0 here?">;
+def ext_forward_ref_enum : Extension<
+ "ISO C forbids forward references to 'enum' types">;
+def err_forward_ref_enum : Error<
"ISO C++ forbids forward references to 'enum' types">; def ext_ms_forward_ref_enum : Extension< "forward references to 'enum' types are a Microsoft extension">, InGroup<Microsoft>; @@ -3239,17 +3245,19 @@ def err_array_too_large : Error< def warn_array_new_too_large : Warning<"array is too large (%0 elements)">, // FIXME PR11644: ", will throw std::bad_array_new_length at runtime" InGroup<DiagGroup<"bad-array-new-length">>; - -// -Wpadded, -Wpacked -def warn_padded_struct_field : Warning< - "padding %select{struct|class}0 %1 with %2 %select{byte|bit}3%select{|s}4 " - "to align %5">, InGroup<Padded>, DefaultIgnore; -def warn_padded_struct_anon_field : Warning< - "padding %select{struct|class}0 %1 with %2 %select{byte|bit}3%select{|s}4 " - "to align anonymous bit-field">, InGroup<Padded>, DefaultIgnore; -def warn_padded_struct_size : Warning< - "padding size of %0 with %1 %select{byte|bit}2%select{|s}3 " - "to alignment boundary">, InGroup<Padded>, DefaultIgnore; +
+// -Wpadded, -Wpacked
+def warn_padded_struct_field : Warning<
+ "padding %select{struct|interface|class}0 %1 with %2 "
+ "%select{byte|bit}3%select{|s}4 to align %5">,
+ InGroup<Padded>, DefaultIgnore;
+def warn_padded_struct_anon_field : Warning<
+ "padding %select{struct|interface|class}0 %1 with %2 "
+ "%select{byte|bit}3%select{|s}4 to align anonymous bit-field">,
+ InGroup<Padded>, DefaultIgnore;
+def warn_padded_struct_size : Warning<
+ "padding size of %0 with %1 %select{byte|bit}2%select{|s}3 "
+ "to alignment boundary">, InGroup<Padded>, DefaultIgnore;
def warn_unnecessary_packed : Warning< "packed attribute is unnecessary for %0">, InGroup<Packed>, DefaultIgnore; @@ -3491,20 +3499,22 @@ def ext_flexible_array_in_struct : Extension< def ext_flexible_array_in_array : Extension< "%0 may not be used as an array element due to flexible array member">, InGroup<FlexibleArrayExtensions>; -def err_flexible_array_init : Error< - "initialization of flexible array member is not allowed">; -def ext_flexible_array_empty_aggregate_ms : Extension< - "flexible array member %0 in otherwise empty %select{struct|class}1 " - "is a Microsoft extension">, InGroup<Microsoft>; -def ext_flexible_array_union_ms : Extension< - "flexible array member %0 in a union is a Microsoft extension">, - InGroup<Microsoft>; -def ext_flexible_array_empty_aggregate_gnu : Extension< - "flexible array member %0 in otherwise empty %select{struct|class}1 " - "is a GNU extension">, InGroup<GNU>; -def ext_flexible_array_union_gnu : Extension< - "flexible array member %0 in a union is a GNU extension">, InGroup<GNU>; - +def err_flexible_array_init : Error<
+ "initialization of flexible array member is not allowed">;
+def ext_flexible_array_empty_aggregate_ms : Extension<
+ "flexible array member %0 in otherwise empty "
+ "%select{struct|interface|union|class|enum}1 is a Microsoft extension">,
+ InGroup<Microsoft>;
+def ext_flexible_array_union_ms : Extension<
+ "flexible array member %0 in a union is a Microsoft extension">,
+ InGroup<Microsoft>;
+def ext_flexible_array_empty_aggregate_gnu : Extension<
+ "flexible array member %0 in otherwise empty "
+ "%select{struct|interface|union|class|enum}1 is a GNU extension">,
+ InGroup<GNU>;
+def ext_flexible_array_union_gnu : Extension<
+ "flexible array member %0 in a union is a GNU extension">, InGroup<GNU>;
+
let CategoryName = "ARC Semantic Issue" in { // ARC-mode diagnostics. @@ -4584,13 +4594,13 @@ def err_invalid_declarator_scope : Error<"cannot define or redeclare %0 here " "because namespace %1 does not enclose namespace %2">; def err_invalid_declarator_global_scope : Error< "definition or redeclaration of %0 cannot name the global scope">; -def err_invalid_declarator_in_function : Error< - "definition or redeclaration of %0 not allowed inside a function">; -def err_not_tag_in_scope : Error< - "no %select{struct|union|class|enum}0 named %1 in %2">; - -def err_no_typeid_with_fno_rtti : Error< - "cannot use typeid with -fno-rtti">; +def err_invalid_declarator_in_function : Error<
+ "definition or redeclaration of %0 not allowed inside a function">;
+def err_not_tag_in_scope : Error<
+ "no %select{struct|interface|union|class|enum}0 named %1 in %2">;
+
+def err_no_typeid_with_fno_rtti : Error<
+ "cannot use typeid with -fno-rtti">;
def err_cannot_form_pointer_to_member_of_reference_type : Error< "cannot form a pointer-to-member to member %0 of reference type %1">; @@ -5935,13 +5945,13 @@ def err_module_private_specialization : Error< "%select{template|partial|member}0 specialization cannot be " "declared __module_private__">; def err_module_private_local : Error< - "%select{local variable|parameter|typedef}0 %1 cannot be declared " - "__module_private__">; -def err_module_private_local_class : Error< - "local %select{struct|union|class|enum}0 cannot be declared " - "__module_private__">; -def err_module_private_definition : Error< - "definition of %0 must be imported before it is required">; + "%select{local variable|parameter|typedef}0 %1 cannot be declared "
+ "__module_private__">;
+def err_module_private_local_class : Error<
+ "local %select{struct|interface|union|class|enum}0 cannot be declared "
+ "__module_private__">;
+def err_module_private_definition : Error<
+ "definition of %0 must be imported before it is required">;
} let CategoryName = "Documentation Issue" in { diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h index 96cada1057..1d39c4bdcf 100644 --- a/include/clang/Basic/Specifiers.h +++ b/include/clang/Basic/Specifiers.h @@ -50,12 +50,13 @@ namespace clang { TST_decimal64, // _Decimal64 TST_decimal128, // _Decimal128 TST_enum, - TST_union, - TST_struct, - TST_class, // C++ class type - TST_typename, // Typedef, C++ class-name or enum name, etc. - TST_typeofType, - TST_typeofExpr, + TST_union,
+ TST_struct,
+ TST_class, // C++ class type
+ TST_interface, // C++ (Microsoft-specific) __interface type
+ TST_typename, // Typedef, C++ class-name or enum name, etc.
+ TST_typeofType,
+ TST_typeofExpr,
TST_decltype, // C++0x decltype TST_underlyingType, // __underlying_type for C++0x TST_auto, // C++0x auto diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def index fc031914a8..fd0437c07b 100644 --- a/include/clang/Basic/TokenKinds.def +++ b/include/clang/Basic/TokenKinds.def @@ -505,6 +505,7 @@ KEYWORD(__if_not_exists , KEYMS) KEYWORD(__single_inheritance , KEYMS) KEYWORD(__multiple_inheritance , KEYMS) KEYWORD(__virtual_inheritance , KEYMS) +KEYWORD(__interface , KEYMS) ALIAS("__int8" , char , KEYMS) ALIAS("__int16" , short , KEYMS) ALIAS("__int32" , int , KEYMS) @@ -518,7 +519,6 @@ ALIAS("_thiscall" , __thiscall , KEYMS) ALIAS("_uuidof" , __uuidof , KEYMS | KEYBORLAND) ALIAS("_inline" , inline , KEYMS) ALIAS("_declspec" , __declspec , KEYMS) -ALIAS("__interface" , struct , KEYMS) // Borland Extensions which should be disabled in strict conformance mode. ALIAS("_pascal" , __pascal , KEYBORLAND) diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index 792b0c643d..9723a43c91 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -266,6 +266,7 @@ public: static const TST TST_enum = clang::TST_enum; static const TST TST_union = clang::TST_union; static const TST TST_struct = clang::TST_struct; + static const TST TST_interface = clang::TST_interface; static const TST TST_class = clang::TST_class; static const TST TST_typename = clang::TST_typename; static const TST TST_typeofType = clang::TST_typeofType; @@ -378,7 +379,8 @@ private: } static bool isDeclRep(TST T) { return (T == TST_enum || T == TST_struct || - T == TST_union || T == TST_class); + T == TST_interface || T == TST_union || + T == TST_class); } DeclSpec(const DeclSpec&); // DO NOT IMPLEMENT diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 2f21e4cbd6..c68a16bdae 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -463,13 +463,14 @@ void CXXRecordDecl::markedConstructorConstexpr(CXXConstructorDecl *CD) { } void CXXRecordDecl::addedMember(Decl *D) { - if (!D->isImplicit() && - !isa<FieldDecl>(D) && - !isa<IndirectFieldDecl>(D) && - (!isa<TagDecl>(D) || cast<TagDecl>(D)->getTagKind() == TTK_Class)) - data().HasOnlyCMembers = false; - - // Ignore friends and invalid declarations. + if (!D->isImplicit() &&
+ !isa<FieldDecl>(D) &&
+ !isa<IndirectFieldDecl>(D) &&
+ (!isa<TagDecl>(D) || cast<TagDecl>(D)->getTagKind() == TTK_Class ||
+ cast<TagDecl>(D)->getTagKind() == TTK_Interface))
+ data().HasOnlyCMembers = false;
+
+ // Ignore friends and invalid declarations.
if (D->getFriendObjectKind() || D->isInvalidDecl()) return; @@ -933,13 +934,14 @@ NotASpecialMember:; if (Shadow->getDeclName().getNameKind() == DeclarationName::CXXConversionFunctionName) data().Conversions.addDecl(Shadow, Shadow->getAccess()); -} - -bool CXXRecordDecl::isCLike() const { - if (getTagKind() == TTK_Class || !TemplateOrInstantiation.isNull()) - return false; - if (!hasDefinition()) - return true; +}
+
+bool CXXRecordDecl::isCLike() const {
+ if (getTagKind() == TTK_Class || getTagKind() == TTK_Interface ||
+ !TemplateOrInstantiation.isNull())
+ return false;
+ if (!hasDefinition())
+ return true;
return isPOD() && data().HasOnlyCMembers; } diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index 982e3aceec..f0041b2422 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/lib/AST/MicrosoftMangle.cpp @@ -1270,12 +1270,13 @@ void MicrosoftCXXNameMangler::mangleType(const RecordType *T, SourceRange) { void MicrosoftCXXNameMangler::mangleType(const TagType *T) { switch (T->getDecl()->getTagKind()) { case TTK_Union: - Out << 'T'; - break; - case TTK_Struct: - Out << 'U'; - break; - case TTK_Class: < |