diff options
Diffstat (limited to 'lib/Sema/SemaDeclAttr.cpp')
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 223 |
1 files changed, 171 insertions, 52 deletions
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index c96ab46..b2124fe 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -177,9 +177,10 @@ static void HandleExtVectorTypeAttr(Scope *scope, Decl *d, // Special case where the argument is a template id. if (Attr.getParameterName()) { - sizeExpr = S.ActOnDeclarationNameExpr(scope, Attr.getLoc(), - Attr.getParameterName(), - false, 0, false).takeAs<Expr>(); + CXXScopeSpec SS; + UnqualifiedId id; + id.setIdentifier(Attr.getParameterName(), Attr.getLoc()); + sizeExpr = S.ActOnIdExpression(scope, SS, id, false, false).takeAs<Expr>(); } else { // check the attribute arguments. if (Attr.getNumArgs() != 1) { @@ -410,12 +411,9 @@ static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - const char *Alias = Str->getStrData(); - unsigned AliasLen = Str->getByteLength(); - // FIXME: check if target symbol exists in current file - d->addAttr(::new (S.Context) AliasAttr(std::string(Alias, AliasLen))); + d->addAttr(::new (S.Context) AliasAttr(Str->getString())); } static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, @@ -464,7 +462,9 @@ static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr, if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) { ValueDecl *VD = dyn_cast<ValueDecl>(d); if (VD == 0 || !VD->getType()->isBlockPointerType()) { - S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) + S.Diag(Attr.getLoc(), + Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type + : diag::warn_attribute_wrong_decl_type) << Attr.getName() << 0 /*function*/; return false; } @@ -484,6 +484,15 @@ static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr, d->addAttr(::new (S.Context) AnalyzerNoReturnAttr()); } +static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) { + if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) { + S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) + << Attr.getName() << 8; /*function, method, or parameter*/ + return; + } + // FIXME: Actually store the attribute on the declaration +} + static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) { // check the attribute arguments. if (Attr.getNumArgs() != 0) { @@ -994,12 +1003,10 @@ static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) { return; } - std::string SectionStr(SE->getStrData(), SE->getByteLength()); - // If the target wants to validate the section specifier, make it happen. - std::string Error = S.Context.Target.isValidSectionSpecifier(SectionStr); + std::string Error = S.Context.Target.isValidSectionSpecifier(SE->getString()); if (Error.empty()) { - D->addAttr(::new (S.Context) SectionAttr(SectionStr)); + D->addAttr(::new (S.Context) SectionAttr(SE->getString())); return; } @@ -1506,8 +1513,7 @@ static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) { S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate"; return; } - d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(), - SE->getByteLength()))); + d->addAttr(::new (S.Context) AnnotateAttr(SE->getString())); } static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -1516,6 +1522,10 @@ static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) { S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; return; } + + //FIXME: The C++0x version of this attribute has more limited applicabilty + // than GNU's, and should error out when it is used to specify a + // weaker alignment, rather than being silently ignored. unsigned Align = 0; if (Attr.getNumArgs() == 0) { @@ -1794,6 +1804,108 @@ static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) { d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue())); } +static void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) { + // check the attribute arguments. + if (Attr.getNumArgs() != 0) { + S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; + return; + } + + if (!isa<CXXRecordDecl>(d) + && (!isa<CXXMethodDecl>(d) || !cast<CXXMethodDecl>(d)->isVirtual())) { + S.Diag(Attr.getLoc(), + Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type + : diag::warn_attribute_wrong_decl_type) + << Attr.getName() << 7 /*virtual method or class*/; + return; + } + + // 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. //===----------------------------------------------------------------------===// @@ -1841,7 +1953,8 @@ static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr, /// ProcessDeclAttribute - Apply the specific attribute to the specified decl if /// the attribute applies to decls. If the attribute is a type attribute, just -/// silently ignore it. +/// silently ignore it if a GNU attribute. FIXME: Applying a C++0x attribute to +/// the wrong thing is illegal (C++0x [dcl.attr.grammar]/4). static void ProcessDeclAttribute(Scope *scope, Decl *D, const AttributeList &Attr, Sema &S) { if (Attr.isDeclspecAttribute()) @@ -1854,31 +1967,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_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_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; case AttributeList::AT_ext_vector_type: HandleExtVectorTypeAttr(scope, D, Attr, S); break; - case AttributeList::AT_fastcall: HandleFastCallAttr (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: @@ -1888,18 +2007,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; @@ -1907,15 +2026,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 |