зеркало из https://github.com/microsoft/clang-1.git
Parse C++ member check attributes - base_check, hiding, and override.
The attributes are currently ignored. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89837 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
717a5955e9
Коммит
7725e67639
|
@ -49,6 +49,7 @@ public:
|
|||
AnalyzerNoReturn, // Clang-specific.
|
||||
Annotate,
|
||||
AsmLabel, // Represent GCC asm label extension.
|
||||
BaseCheck,
|
||||
Blocks,
|
||||
CDecl,
|
||||
Cleanup,
|
||||
|
@ -63,6 +64,7 @@ public:
|
|||
Format,
|
||||
FormatArg,
|
||||
GNUInline,
|
||||
Hiding,
|
||||
IBOutletKind, // Clang-specific. Use "Kind" suffix to not conflict with
|
||||
Malloc,
|
||||
NoDebug,
|
||||
|
@ -72,6 +74,7 @@ public:
|
|||
NoThrow,
|
||||
ObjCException,
|
||||
ObjCNSObject,
|
||||
Override,
|
||||
CFReturnsRetained, // Clang/Checker-specific.
|
||||
NSReturnsRetained, // Clang/Checker-specific.
|
||||
Overloadable, // Clang-specific
|
||||
|
@ -558,6 +561,11 @@ public:
|
|||
DEF_SIMPLE_ATTR(CFReturnsRetained);
|
||||
DEF_SIMPLE_ATTR(NSReturnsRetained);
|
||||
|
||||
// C++0x member checking attributes.
|
||||
DEF_SIMPLE_ATTR(BaseCheck);
|
||||
DEF_SIMPLE_ATTR(Hiding);
|
||||
DEF_SIMPLE_ATTR(Override);
|
||||
|
||||
#undef DEF_SIMPLE_ATTR
|
||||
|
||||
} // end namespace clang
|
||||
|
|
|
@ -551,6 +551,9 @@ def err_auto_not_allowed : Error<
|
|||
"|class member|exception declaration|template parameter|block literal}0">;
|
||||
def err_auto_var_requires_init : Error<
|
||||
"declaration of variable %0 with type %1 requires an initializer">;
|
||||
|
||||
// C++0x attributes
|
||||
def err_repeat_attribute : Error<"'%0' attribute cannot be repeated">;
|
||||
|
||||
// C++0x [[final]]
|
||||
def err_final_function_overridden : Error<
|
||||
|
@ -646,12 +649,14 @@ def warn_attribute_wrong_decl_type : Warning<
|
|||
"%0 attribute only applies to %select{function|union|"
|
||||
"variable and function|function or method|parameter|"
|
||||
"parameter or Objective-C method |function, method or block|"
|
||||
"virtual method or class|function, method, or parameter}1 types">;
|
||||
"virtual method or class|function, method, or parameter|class|virtual method"
|
||||
"|member}1 types">;
|
||||
def err_attribute_wrong_decl_type : Error<
|
||||
"%0 attribute only applies to %select{function|union|"
|
||||
"variable and function|function or method|parameter|"
|
||||
"parameter or Objective-C method |function, method or block|"
|
||||
"virtual method or class|function, method, or parameter}1 types">;
|
||||
"virtual method or class|function, method, or parameter|class|virtual method"
|
||||
"|member}1 types">;
|
||||
def warn_gnu_inline_attribute_requires_inline : Warning<
|
||||
"'gnu_inline' attribute requires function to be marked 'inline',"
|
||||
" attribute ignored">;
|
||||
|
|
|
@ -59,6 +59,7 @@ public:
|
|||
AT_always_inline,
|
||||
AT_analyzer_noreturn,
|
||||
AT_annotate,
|
||||
AT_base_check,
|
||||
AT_blocks,
|
||||
AT_carries_dependency,
|
||||
AT_cdecl,
|
||||
|
@ -75,6 +76,7 @@ public:
|
|||
AT_format,
|
||||
AT_format_arg,
|
||||
AT_gnu_inline,
|
||||
AT_hiding,
|
||||
AT_malloc,
|
||||
AT_mode,
|
||||
AT_nodebug,
|
||||
|
@ -85,6 +87,7 @@ public:
|
|||
AT_nothrow,
|
||||
AT_nsobject,
|
||||
AT_objc_exception,
|
||||
AT_override,
|
||||
AT_cf_returns_retained, // Clang-specific.
|
||||
AT_ns_returns_retained, // Clang-specific.
|
||||
AT_objc_gc,
|
||||
|
|
|
@ -441,6 +441,7 @@ Attr *PCHReader::ReadAttributes() {
|
|||
SIMPLE_ATTR(AnalyzerNoReturn);
|
||||
STRING_ATTR(Annotate);
|
||||
STRING_ATTR(AsmLabel);
|
||||
SIMPLE_ATTR(BaseCheck);
|
||||
|
||||
case Attr::Blocks:
|
||||
New = ::new (*Context) BlocksAttr(
|
||||
|
@ -485,6 +486,7 @@ Attr *PCHReader::ReadAttributes() {
|
|||
}
|
||||
|
||||
SIMPLE_ATTR(GNUInline);
|
||||
SIMPLE_ATTR(Hiding);
|
||||
|
||||
case Attr::IBOutletKind:
|
||||
New = ::new (*Context) IBOutletAttr();
|
||||
|
@ -518,6 +520,7 @@ Attr *PCHReader::ReadAttributes() {
|
|||
SIMPLE_ATTR(CFReturnsRetained);
|
||||
SIMPLE_ATTR(NSReturnsRetained);
|
||||
SIMPLE_ATTR(Overloadable);
|
||||
SIMPLE_ATTR(Override);
|
||||
SIMPLE_ATTR(Packed);
|
||||
UNSIGNED_ATTR(PragmaPack);
|
||||
SIMPLE_ATTR(Pure);
|
||||
|
|
|
@ -1764,6 +1764,9 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
|
|||
AddString(cast<AsmLabelAttr>(Attr)->getLabel(), Record);
|
||||
break;
|
||||
|
||||
case Attr::BaseCheck:
|
||||
break;
|
||||
|
||||
case Attr::Blocks:
|
||||
Record.push_back(cast<BlocksAttr>(Attr)->getType()); // FIXME: stable
|
||||
break;
|
||||
|
@ -1817,6 +1820,7 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
|
|||
}
|
||||
|
||||
case Attr::GNUInline:
|
||||
case Attr::Hiding:
|
||||
case Attr::IBOutletKind:
|
||||
case Attr::Malloc:
|
||||
case Attr::NoDebug:
|
||||
|
@ -1837,6 +1841,7 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
|
|||
case Attr::CFReturnsRetained:
|
||||
case Attr::NSReturnsRetained:
|
||||
case Attr::Overloadable:
|
||||
case Attr::Override:
|
||||
break;
|
||||
|
||||
case Attr::PragmaPack:
|
||||
|
|
|
@ -65,11 +65,12 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
|
|||
.Case("final", AT_final)
|
||||
.Case("cdecl", AT_cdecl)
|
||||
.Case("const", AT_const)
|
||||
.Case("packed", AT_packed)
|
||||
.Case("malloc", AT_malloc)
|
||||
.Case("format", AT_format)
|
||||
.Case("unused", AT_unused)
|
||||
.Case("blocks", AT_blocks)
|
||||
.Case("format", AT_format)
|
||||
.Case("hiding", AT_hiding)
|
||||
.Case("malloc", AT_malloc)
|
||||
.Case("packed", AT_packed)
|
||||
.Case("unused", AT_unused)
|
||||
.Case("aligned", AT_aligned)
|
||||
.Case("cleanup", AT_cleanup)
|
||||
.Case("nodebug", AT_nodebug)
|
||||
|
@ -80,15 +81,17 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
|
|||
.Case("section", AT_section)
|
||||
.Case("stdcall", AT_stdcall)
|
||||
.Case("annotate", AT_annotate)
|
||||
.Case("noreturn", AT_noreturn)
|
||||
.Case("noinline", AT_noinline)
|
||||
.Case("fastcall", AT_fastcall)
|
||||
.Case("iboutlet", AT_IBOutlet)
|
||||
.Case("noreturn", AT_noreturn)
|
||||
.Case("noinline", AT_noinline)
|
||||
.Case("override", AT_override)
|
||||
.Case("sentinel", AT_sentinel)
|
||||
.Case("NSObject", AT_nsobject)
|
||||
.Case("dllimport", AT_dllimport)
|
||||
.Case("dllexport", AT_dllexport)
|
||||
.Case("may_alias", IgnoredAttribute) // FIXME: TBAA
|
||||
.Case("base_check", AT_base_check)
|
||||
.Case("deprecated", AT_deprecated)
|
||||
.Case("visibility", AT_visibility)
|
||||
.Case("destructor", AT_destructor)
|
||||
|
|
|
@ -1699,9 +1699,12 @@ CXX0XAttributeList Parser::ParseCXX0XAttributes(SourceLocation *EndLoc) {
|
|||
switch(AttributeList::getKind(AttrName))
|
||||
{
|
||||
// No arguments
|
||||
case AttributeList::AT_noreturn:
|
||||
case AttributeList::AT_base_check:
|
||||
case AttributeList::AT_carries_dependency:
|
||||
case AttributeList::AT_final:
|
||||
case AttributeList::AT_carries_dependency: {
|
||||
case AttributeList::AT_hiding:
|
||||
case AttributeList::AT_noreturn:
|
||||
case AttributeList::AT_override: {
|
||||
if (Tok.is(tok::l_paren)) {
|
||||
Diag(Tok.getLocation(), diag::err_cxx0x_attribute_forbids_arguments)
|
||||
<< AttrName->getName();
|
||||
|
|
|
@ -1825,14 +1825,93 @@ static void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) {
|
|||
<< Attr.getName() << 7 /*virtual method or class*/;
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: Check that it's not specified more than once in an attribute-
|
||||
// specifier and that it conforms to the C++0x rules for
|
||||
// redeclarations.
|
||||
|
||||
// FIXME: Conform to C++0x redeclaration rules.
|
||||
|
||||
if (d->getAttr<FinalAttr>()) {
|
||||
S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "final";
|
||||
return;
|
||||
}
|
||||
|
||||
d->addAttr(::new (S.Context) FinalAttr());
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// C++0x member checking attributes
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static void HandleBaseCheckAttr(Decl *d, const AttributeList &Attr, Sema &S) {
|
||||
if (Attr.getNumArgs() != 0) {
|
||||
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isa<CXXRecordDecl>(d)) {
|
||||
S.Diag(Attr.getLoc(),
|
||||
Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
|
||||
: diag::warn_attribute_wrong_decl_type)
|
||||
<< Attr.getName() << 9 /*class*/;
|
||||
return;
|
||||
}
|
||||
|
||||
if (d->getAttr<BaseCheckAttr>()) {
|
||||
S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "base_check";
|
||||
return;
|
||||
}
|
||||
|
||||
d->addAttr(::new (S.Context) BaseCheckAttr());
|
||||
}
|
||||
|
||||
static void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) {
|
||||
if (Attr.getNumArgs() != 0) {
|
||||
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isa<RecordDecl>(d->getDeclContext())) {
|
||||
// FIXME: It's not the type that's the problem
|
||||
S.Diag(Attr.getLoc(),
|
||||
Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
|
||||
: diag::warn_attribute_wrong_decl_type)
|
||||
<< Attr.getName() << 11 /*member*/;
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: Conform to C++0x redeclaration rules.
|
||||
|
||||
if (d->getAttr<HidingAttr>()) {
|
||||
S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "hiding";
|
||||
return;
|
||||
}
|
||||
|
||||
d->addAttr(::new (S.Context) HidingAttr());
|
||||
}
|
||||
|
||||
static void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) {
|
||||
if (Attr.getNumArgs() != 0) {
|
||||
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual()) {
|
||||
// FIXME: It's not the type that's the problem
|
||||
S.Diag(Attr.getLoc(),
|
||||
Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
|
||||
: diag::warn_attribute_wrong_decl_type)
|
||||
<< Attr.getName() << 10 /*virtual method*/;
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: Conform to C++0x redeclaration rules.
|
||||
|
||||
if (d->getAttr<OverrideAttr>()) {
|
||||
S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "override";
|
||||
return;
|
||||
}
|
||||
|
||||
d->addAttr(::new (S.Context) OverrideAttr());
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Checker-specific attribute handlers.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -1894,34 +1973,37 @@ static void ProcessDeclAttribute(Scope *scope, Decl *D,
|
|||
// Ignore these, these are type attributes, handled by
|
||||
// ProcessTypeAttributes.
|
||||
break;
|
||||
case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_alias: HandleAliasAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_aligned: HandleAlignedAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_always_inline:
|
||||
HandleAlwaysInlineAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_analyzer_noreturn:
|
||||
HandleAnalyzerNoReturnAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_base_check: HandleBaseCheckAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_carries_dependency:
|
||||
HandleDependencyAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_cdecl: HandleCDeclAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_constructor: HandleConstructorAttr(D, Attr, S); break;
|
||||
case AttributeList::AT_deprecated: HandleDeprecatedAttr(D, Attr, S); break;
|
||||
case AttributeList::AT_destructor: HandleDestructorAttr(D, Attr, S); break;
|
||||
case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break;
|
||||
HandleDependencyAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_cdecl: HandleCDeclAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_constructor: HandleConstructorAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_deprecated: HandleDeprecatedAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_destructor: HandleDestructorAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_dllexport: HandleDLLExportAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_dllimport: HandleDLLImportAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_ext_vector_type:
|
||||
HandleExtVectorTypeAttr(scope, D, Attr, S);
|
||||
break;
|
||||
case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_final: HandleFinalAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_gnu_inline: HandleGNUInlineAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_fastcall: HandleFastCallAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_final: HandleFinalAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_format_arg: HandleFormatArgAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_gnu_inline: HandleGNUInlineAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_hiding: HandleHidingAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_mode: HandleModeAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_malloc: HandleMallocAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_override: HandleOverrideAttr (D, Attr, S); break;
|
||||
|
||||
// Checker-specific.
|
||||
case AttributeList::AT_ns_returns_retained:
|
||||
|
@ -1931,18 +2013,18 @@ static void ProcessDeclAttribute(Scope *scope, Decl *D,
|
|||
case AttributeList::AT_reqd_wg_size:
|
||||
HandleReqdWorkGroupSize(D, Attr, S); break;
|
||||
|
||||
case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_unavailable: HandleUnavailableAttr(D, Attr, S); break;
|
||||
case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_vector_size: HandleVectorSizeAttr(D, Attr, S); break;
|
||||
case AttributeList::AT_visibility: HandleVisibilityAttr(D, Attr, S); break;
|
||||
case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_unused: HandleUnusedAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_used: HandleUsedAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_vector_size: HandleVectorSizeAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_visibility: HandleVisibilityAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_warn_unused_result: HandleWarnUnusedResult(D,Attr,S);
|
||||
break;
|
||||
case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_weak_import: HandleWeakImportAttr(D, Attr, S); break;
|
||||
case AttributeList::AT_weak: HandleWeakAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_weak_import: HandleWeakImportAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_transparent_union:
|
||||
HandleTransparentUnionAttr(D, Attr, S);
|
||||
break;
|
||||
|
@ -1950,15 +2032,15 @@ static void ProcessDeclAttribute(Scope *scope, Decl *D,
|
|||
HandleObjCExceptionAttr(D, Attr, S);
|
||||
break;
|
||||
case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
|
||||
case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break;
|
||||
case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break;
|
||||
case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_nodebug: HandleNoDebugAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_noinline: HandleNoInlineAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_regparm: HandleRegparmAttr (D, Attr, S); break;
|
||||
case AttributeList::IgnoredAttribute:
|
||||
case AttributeList::AT_no_instrument_function: // Interacts with -pg.
|
||||
// Just ignore
|
||||
|
|
|
@ -22,3 +22,15 @@ static_assert(alignof(align_small) == alignof(int), "j's alignment is wrong");
|
|||
static_assert(alignof(align_multiple) == 8, "l's alignment is wrong");
|
||||
static_assert(alignof(align_member) == 8, "quuux's alignment is wrong");
|
||||
static_assert(sizeof(align_member) == 8, "quuux's size is wrong");
|
||||
|
||||
int bc_fail [[base_check]]; // expected-error {{'base_check' attribute only applies to class types}}
|
||||
int hiding_fail [[hiding]]; // expected-error {{'hiding' attribute only applies to member types}}
|
||||
int override_fail [[override]]; // expected-error {{'override' attribute only applies to virtual method types}}
|
||||
|
||||
struct base {
|
||||
virtual void function();
|
||||
virtual void other_function();
|
||||
};
|
||||
|
||||
struct [[base_check, base_check]] bc : base { // expected-error {{'base_check' attribute cannot be repeated}}
|
||||
};
|
Загрузка…
Ссылка в новой задаче