diff options
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 675 |
1 files changed, 3 insertions, 672 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index b954c8b2e11..0b048b0a0af 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -19,13 +19,13 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/Type.h" #include "clang/Parse/DeclSpec.h" #include "clang/Parse/Scope.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/SourceManager.h" -#include "clang/AST/ExprCXX.h" // FIXME: layering (ideally, Sema shouldn't be dependent on Lex API's) #include "clang/Lex/Preprocessor.h" #include "clang/Lex/HeaderSearch.h" @@ -260,7 +260,8 @@ TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) { return New; } -/// DeclhasAttr - returns true if decl Declaration already has the target attribute. +/// DeclhasAttr - returns true if decl Declaration already has the target +/// attribute. static bool DeclHasAttr(const Decl *decl, const Attr *target) { for (const Attr *attr = decl->getAttrs(); attr; attr = attr->getNext()) if (attr->getKind() == target->getKind()) @@ -2325,673 +2326,3 @@ Sema::DeclTy* Sema::ActOnLinkageSpec(SourceLocation Loc, // FIXME: Add all the various semantics of linkage specifications return LinkageSpecDecl::Create(Context, Loc, Language, dcl); } - -void Sema::HandleDeclAttribute(Decl *New, const AttributeList *Attr) { - - switch (Attr->getKind()) { - case AttributeList::AT_vector_size: - if (ValueDecl *vDecl = dyn_cast<ValueDecl>(New)) { - QualType newType = HandleVectorTypeAttribute(vDecl->getType(), Attr); - if (!newType.isNull()) // install the new vector type into the decl - vDecl->setType(newType); - } - if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New)) { - QualType newType = HandleVectorTypeAttribute(tDecl->getUnderlyingType(), - Attr); - if (!newType.isNull()) // install the new vector type into the decl - tDecl->setUnderlyingType(newType); - } - break; - case AttributeList::AT_ext_vector_type: - if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New)) - HandleExtVectorTypeAttribute(tDecl, Attr); - else - Diag(Attr->getLoc(), - diag::err_typecheck_ext_vector_not_typedef); - break; - case AttributeList::AT_address_space: - // Ignore this, this is a type attribute, handled by ProcessTypeAttributes. - break; - case AttributeList::AT_mode: - // Despite what would be logical, the mode attribute is a decl attribute, - // not a type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make - // 'G' be HImode, not an intermediate pointer. - if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New)) { - QualType newType = HandleModeTypeAttribute(tDecl->getUnderlyingType(), - Attr); - tDecl->setUnderlyingType(newType); - } else if (ValueDecl *vDecl = dyn_cast<ValueDecl>(New)) { - QualType newType = HandleModeTypeAttribute(vDecl->getType(), Attr); - vDecl->setType(newType); - } - // FIXME: Diagnostic? - break; - case AttributeList::AT_alias: - HandleAliasAttribute(New, Attr); - break; - case AttributeList::AT_deprecated: - HandleDeprecatedAttribute(New, Attr); - break; - case AttributeList::AT_visibility: - HandleVisibilityAttribute(New, Attr); - break; - case AttributeList::AT_weak: - HandleWeakAttribute(New, Attr); - break; - case AttributeList::AT_dllimport: - HandleDLLImportAttribute(New, Attr); - break; - case AttributeList::AT_dllexport: - HandleDLLExportAttribute(New, Attr); - break; - case AttributeList::AT_nothrow: - HandleNothrowAttribute(New, Attr); - break; - case AttributeList::AT_stdcall: - HandleStdCallAttribute(New, Attr); - break; - case AttributeList::AT_fastcall: - HandleFastCallAttribute(New, Attr); - break; - case AttributeList::AT_aligned: - HandleAlignedAttribute(New, Attr); - break; - case AttributeList::AT_packed: - HandlePackedAttribute(New, Attr); - break; - case AttributeList::AT_annotate: - HandleAnnotateAttribute(New, Attr); - break; - case AttributeList::AT_noreturn: - HandleNoReturnAttribute(New, Attr); - break; - case AttributeList::AT_format: - HandleFormatAttribute(New, Attr); - break; - case AttributeList::AT_transparent_union: - HandleTransparentUnionAttribute(New, Attr); - break; - default: -#if 0 - // TODO: when we have the full set of attributes, warn about unknown ones. - Diag(Attr->getLoc(), diag::warn_attribute_ignored, - Attr->getName()->getName()); -#endif - break; - } -} - -void Sema::HandleDeclAttributes(Decl *New, const AttributeList *DeclSpecAttrs, - const AttributeList *DeclaratorAttrs) { - if (DeclSpecAttrs == 0 && DeclaratorAttrs == 0) return; - - while (DeclSpecAttrs) { - HandleDeclAttribute(New, DeclSpecAttrs); - DeclSpecAttrs = DeclSpecAttrs->getNext(); - } - - // If there are any type attributes that were in the declarator, apply them to - // its top level type. - if (ValueDecl *VD = dyn_cast<ValueDecl>(New)) { - QualType DT = VD->getType(); - ProcessTypeAttributes(DT, DeclaratorAttrs); - VD->setType(DT); - } else if (TypedefDecl *TD = dyn_cast<TypedefDecl>(New)) { - QualType DT = TD->getUnderlyingType(); - ProcessTypeAttributes(DT, DeclaratorAttrs); - TD->setUnderlyingType(DT); - } - - while (DeclaratorAttrs) { - HandleDeclAttribute(New, DeclaratorAttrs); - DeclaratorAttrs = DeclaratorAttrs->getNext(); - } -} - -void Sema::HandleExtVectorTypeAttribute(TypedefDecl *tDecl, - const AttributeList *rawAttr) { - QualType curType = tDecl->getUnderlyingType(); - // check the attribute arguments. - if (rawAttr->getNumArgs() != 1) { - Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, - std::string("1")); - return; - } - Expr *sizeExpr = static_cast<Expr *>(rawAttr->getArg(0)); - llvm::APSInt vecSize(32); - if (!sizeExpr->isIntegerConstantExpr(vecSize, Context)) { - Diag(rawAttr->getLoc(), diag::err_attribute_argument_not_int, - "ext_vector_type", sizeExpr->getSourceRange()); - return; - } - // unlike gcc's vector_size attribute, we do not allow vectors to be defined - // in conjunction with complex types (pointers, arrays, functions, etc.). - Type *canonType = curType.getCanonicalType().getTypePtr(); - if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) { - Diag(rawAttr->getLoc(), diag::err_attribute_invalid_vector_type, - curType.getCanonicalType().getAsString()); - return; - } - // unlike gcc's vector_size attribute, the size is specified as the - // number of elements, not the number of bytes. - unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue()); - - if (vectorSize == 0) { - Diag(rawAttr->getLoc(), diag::err_attribute_zero_size, - sizeExpr->getSourceRange()); - return; - } - // Instantiate/Install the vector type, the number of elements is > 0. - tDecl->setUnderlyingType(Context.getExtVectorType(curType, vectorSize)); - // Remember this typedef decl, we will need it later for diagnostics. - ExtVectorDecls.push_back(tDecl); -} - -QualType Sema::HandleVectorTypeAttribute(QualType curType, - const AttributeList *rawAttr) { - // check the attribute arugments. - if (rawAttr->getNumArgs() != 1) { - Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, - std::string("1")); - return QualType(); - } - Expr *sizeExpr = static_cast<Expr *>(rawAttr->getArg(0)); - llvm::APSInt vecSize(32); - if (!sizeExpr->isIntegerConstantExpr(vecSize, Context)) { - Diag(rawAttr->getLoc(), diag::err_attribute_argument_not_int, - "vector_size", sizeExpr->getSourceRange()); - return QualType(); - } - // navigate to the base type - we need to provide for vector pointers, - // vector arrays, and functions returning vectors. - Type *canonType = curType.getCanonicalType().getTypePtr(); - - if (canonType->isPointerType() || canonType->isArrayType() || - canonType->isFunctionType()) { - assert(0 && "HandleVector(): Complex type construction unimplemented"); - /* FIXME: rebuild the type from the inside out, vectorizing the inner type. - do { - if (PointerType *PT = dyn_cast<PointerType>(canonType)) - canonType = PT->getPointeeType().getTypePtr(); - else if (ArrayType *AT = dyn_cast<ArrayType>(canonType)) - canonType = AT->getElementType().getTypePtr(); - else if (FunctionType *FT = dyn_cast<FunctionType>(canonType)) - canonType = FT->getResultType().getTypePtr(); - } while (canonType->isPointerType() || canonType->isArrayType() || - canonType->isFunctionType()); - */ - } - // the base type must be integer or float. - if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) { - Diag(rawAttr->getLoc(), diag::err_attribute_invalid_vector_type, - curType.getCanonicalType().getAsString()); - return QualType(); - } - unsigned typeSize = static_cast<unsigned>(Context.getTypeSize(curType)); - // vecSize is specified in bytes - convert to bits. - unsigned vectorSize = static_cast<unsigned>(vecSize.getZExtValue() * 8); - - // the vector size needs to be an integral multiple of the type size. - if (vectorSize % typeSize) { - Diag(rawAttr->getLoc(), diag::err_attribute_invalid_size, - sizeExpr->getSourceRange()); - return QualType(); - } - if (vectorSize == 0) { - Diag(rawAttr->getLoc(), diag::err_attribute_zero_size, - sizeExpr->getSourceRange()); - return QualType(); - } - // Instantiate the vector type, the number of elements is > 0, and not - // required to be a power of 2, unlike GCC. - return Context.getVectorType(curType, vectorSize/typeSize); -} - -void Sema::HandlePackedAttribute(Decl *d, const AttributeList *rawAttr) { - // check the attribute arguments. - if (rawAttr->getNumArgs() > 0) { - Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, - std::string("0")); - return; - } - - if (TagDecl *TD = dyn_cast<TagDecl>(d)) - TD->addAttr(new PackedAttr); - else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) { - // If the alignment is less than or equal to 8 bits, the packed attribute - // has no effect. - if (!FD->getType()->isIncompleteType() && - Context.getTypeAlign(FD->getType()) <= 8) - Diag(rawAttr->getLoc(), - diag::warn_attribute_ignored_for_field_of_type, - rawAttr->getName()->getName(), FD->getType().getAsString()); - else - FD->addAttr(new PackedAttr); - } else - Diag(rawAttr->getLoc(), diag::warn_attribute_ignored, - rawAttr->getName()->getName()); -} - -void Sema::HandleAliasAttribute(Decl *d, const AttributeList *rawAttr) { - // check the attribute arguments. - if (rawAttr->getNumArgs() != 1) { - Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, - std::string("1")); - return; - } - - Expr *Arg = static_cast<Expr*>(rawAttr->getArg(0)); - Arg = Arg->IgnoreParenCasts(); - StringLiteral *Str = dyn_cast<StringLiteral>(Arg); - - if (Str == 0 || Str->isWide()) { - Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_string, - "alias", std::string("1")); - return; - } - - const char *Alias = Str->getStrData(); - unsigned AliasLen = Str->getByteLength(); - - // FIXME: check if target symbol exists in current file - - d->addAttr(new AliasAttr(std::string(Alias, AliasLen))); -} - -void Sema::HandleNoReturnAttribute(Decl *d, const AttributeList *rawAttr) { - // check the attribute arguments. - if (rawAttr->getNumArgs() != 0) { - Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, - std::string("0")); - return; - } - - FunctionDecl *Fn = dyn_cast<FunctionDecl>(d); - - if (!Fn) { - Diag(rawAttr->getLoc(), diag::warn_attribute_wrong_decl_type, - "noreturn", "function"); - return; - } - - d->addAttr(new NoReturnAttr()); -} - -void Sema::HandleDeprecatedAttribute(Decl *d, const AttributeList *rawAttr) { - // check the attribute arguments. - if (rawAttr->getNumArgs() != 0) { - Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, - std::string("0")); - return; - } - - d->addAttr(new DeprecatedAttr()); -} - -void Sema::HandleVisibilityAttribute(Decl *d, const AttributeList *rawAttr) { - // check the attribute arguments. - if (rawAttr->getNumArgs() != 1) { - Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, - std::string("1")); - return; - } - - Expr *Arg = static_cast<Expr*>(rawAttr->getArg(0)); - Arg = Arg->IgnoreParenCasts(); - StringLiteral *Str = dyn_cast<StringLiteral>(Arg); - - if (Str == 0 || Str->isWide()) { - Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_string, - "visibility", std::string("1")); - return; - } - - const char *TypeStr = Str->getStrData(); - unsigned TypeLen = Str->getByteLength(); - VisibilityAttr::VisibilityTypes type; - - if (TypeLen == 7 && !memcmp(TypeStr, "default", 7)) - type = VisibilityAttr::DefaultVisibility; - else if (TypeLen == 6 && !memcmp(TypeStr, "hidden", 6)) - type = VisibilityAttr::HiddenVisibility; - else if (TypeLen == 8 && !memcmp(TypeStr, "internal", 8)) - type = VisibilityAttr::HiddenVisibility; // FIXME - else if (TypeLen == 9 && !memcmp(TypeStr, "protected", 9)) - type = VisibilityAttr::ProtectedVisibility; - else { - Diag(rawAttr->getLoc(), diag::warn_attribute_type_not_supported, - "visibility", TypeStr); - return; - } - - d->addAttr(new VisibilityAttr(type)); -} - -void Sema::HandleWeakAttribute(Decl *d, const AttributeList *rawAttr) { - // check the attribute arguments. - if (rawAttr->getNumArgs() != 0) { - Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, - std::string("0")); - return; - } - - d->addAttr(new WeakAttr()); -} - -void Sema::HandleDLLImportAttribute(Decl *d, const AttributeList *rawAttr) { - // check the attribute arguments. - if (rawAttr->getNumArgs() != 0) { - Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, - std::string("0")); - return; - } - - d->addAttr(new DLLImportAttr()); -} - -void Sema::HandleDLLExportAttribute(Decl *d, const AttributeList *rawAttr) { - // check the attribute arguments. - if (rawAttr->getNumArgs() != 0) { - Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, - std::string("0")); - return; - } - - d->addAttr(new DLLExportAttr()); -} - -void Sema::HandleStdCallAttribute(Decl *d, const AttributeList *rawAttr) { - // check the attribute arguments. - if (rawAttr->getNumArgs() != 0) { - Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, - std::string("0")); - return; - } - - d->addAttr(new StdCallAttr()); -} - -void Sema::HandleFastCallAttribute(Decl *d, const AttributeList *rawAttr) { - // check the attribute arguments. - if (rawAttr->getNumArgs() != 0) { - Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, - std::string("0")); - return; - } - - d->addAttr(new FastCallAttr()); -} - -void Sema::HandleNothrowAttribute(Decl *d, const AttributeList *rawAttr) { - // check the attribute arguments. - if (rawAttr->getNumArgs() != 0) { - Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, - std::string("0")); - return; - } - - d->addAttr(new NoThrowAttr()); -} - -static const FunctionTypeProto *getFunctionProto(Decl *d) { - QualType Ty; - - if (ValueDecl *decl = dyn_cast<ValueDecl>(d)) - Ty = decl->getType(); - else if (FieldDecl *decl = dyn_cast<FieldDecl>(d)) - Ty = decl->getType(); - else if (TypedefDecl* decl = dyn_cast<TypedefDecl>(d)) - Ty = decl->getUnderlyingType(); - else - return 0; - - if (Ty->isFunctionPointerType()) { - const PointerType *PtrTy = Ty->getAsPointerType(); - Ty = PtrTy->getPointeeType(); - } - - if (const FunctionType *FnTy = Ty->getAsFunctionType()) - return dyn_cast<FunctionTypeProto>(FnTy->getAsFunctionType()); - - return 0; -} - -static inline bool isNSStringType(QualType T, ASTContext &Ctx) { - if (!T->isPointerType()) - return false; - - T = T->getAsPointerType()->getPointeeType().getCanonicalType(); - ObjCInterfaceType* ClsT = dyn_cast<ObjCInterfaceType>(T.getTypePtr()); - - if (!ClsT) - return false; - - IdentifierInfo* ClsName = ClsT->getDecl()->getIdentifier(); - - // FIXME: Should we walk the chain of classes? - return ClsName == &Ctx.Idents.get("NSString") || - ClsName == &Ctx.Idents.get("NSMutableString"); -} - -/// Handle __attribute__((format(type,idx,firstarg))) attributes -/// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html -void Sema::HandleFormatAttribute(Decl *d, const AttributeList *rawAttr) { - - if (!rawAttr->getParameterName()) { - Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_string, - "format", std::string("1")); - return; - } - - if (rawAttr->getNumArgs() != 2) { - Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, - std::string("3")); - return; - } - - // GCC ignores the format attribute on K&R style function - // prototypes, so we ignore it as well - const FunctionTypeProto *proto = getFunctionProto(d); - - if (!proto) { - Diag(rawAttr->getLoc(), diag::warn_attribute_wrong_decl_type, - "format", "function"); - return; - } - - // FIXME: in C++ the implicit 'this' function parameter also counts. - // this is needed in order to be compatible with GCC - // the index must start in 1 and the limit is numargs+1 - unsigned NumArgs = proto->getNumArgs(); - unsigned FirstIdx = 1; - - const char *Format = rawAttr->getParameterName()->getName(); - unsigned FormatLen = rawAttr->getParameterName()->getLength(); - - // Normalize the argument, __foo__ becomes foo. - if (FormatLen > 4 && Format[0] == '_' && Format[1] == '_' && - Format[FormatLen - 2] == '_' && Format[FormatLen - 1] == '_') { - Format += 2; - FormatLen -= 4; - } - - bool Supported = false; - bool is_NSString = false; - bool is_strftime = false; - - switch (FormatLen) { - default: break; - case 5: - Supported = !memcmp(Format, "scanf", 5); - break; - case 6: - Supported = !memcmp(Format, "printf", 6); - break; - case 7: - Supported = !memcmp(Format, "strfmon", 7); - break; - case 8: - Supported = (is_strftime = !memcmp(Format, "strftime", 8)) || - (is_NSString = !memcmp(Format, "NSString", 8)); - break; - } - - if (!Supported) { - Diag(rawAttr->getLoc(), diag::warn_attribute_type_not_supported, - "format", rawAttr->getParameterName()->getName()); - return; - } - - // checks for the 2nd argument - Expr *IdxExpr = static_cast<Expr *>(rawAttr->getArg(0)); - llvm::APSInt Idx(Context.getTypeSize(IdxExpr->getType())); - if (!IdxExpr->isIntegerConstantExpr(Idx, Context)) { - Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_int, - "format", std::string("2"), IdxExpr->getSourceRange()); - return; - } - - if (Idx.getZExtValue() < FirstIdx || Idx.getZExtValue() > NumArgs) { - Diag(rawAttr->getLoc(), diag::err_attribute_argument_out_of_bounds, - "format", std::string("2"), IdxExpr->getSourceRange()); - return; - } - - // FIXME: Do we need to bounds check? - unsigned ArgIdx = Idx.getZExtValue() - 1; - - // make sure the format string is really a string - QualType Ty = proto->getArgType(ArgIdx); - - if (is_NSString) { - // FIXME: do we need to check if the type is NSString*? What are - // the semantics? - if (!isNSStringType(Ty, Context)) { - // FIXME: Should highlight the actual expression that has the - // wrong type. - Diag(rawAttr->getLoc(), diag::err_format_attribute_not_NSString, - IdxExpr->getSourceRange()); - return; - } - } - else if (!Ty->isPointerType() || - !Ty->getAsPointerType()->getPointeeType()->isCharType()) { - // FIXME: Should highlight the actual expression that has the - // wrong type. - Diag(rawAttr->getLoc(), diag::err_format_attribute_not_string, - IdxExpr->getSourceRange()); - return; - } - - // check the 3rd argument - Expr *FirstArgExpr = static_cast<Expr *>(rawAttr->getArg(1)); - llvm::APSInt FirstArg(Context.getTypeSize(FirstArgExpr->getType())); - if (!FirstArgExpr->isIntegerConstantExpr(FirstArg, Context)) { - Diag(rawAttr->getLoc(), diag::err_attribute_argument_n_not_int, - "format", std::string("3"), FirstArgExpr->getSourceRange()); - return; - } - - // check if the function is variadic if the 3rd argument non-zero - if (FirstArg != 0) { - if (proto->isVariadic()) { - ++NumArgs; // +1 for ... - } else { - Diag(d->getLocation(), diag::err_format_attribute_requires_variadic); - return; - } - } - - // strftime requires FirstArg to be 0 because it doesn't read from any variable - // the input is just the current time + the format string - if (is_strftime) { - if (FirstArg != 0) { - Diag(rawAttr->getLoc(), diag::err_format_strftime_third_parameter, - FirstArgExpr->getSourceRange()); - return; - } - // if 0 it disables parameter checking (to use with e.g. va_list) - } else if (FirstArg != 0 && FirstArg != NumArgs) { - Diag(rawAttr->getLoc(), diag::err_attribute_argument_out_of_bounds, - "format", std::string("3"), FirstArgExpr->getSourceRange()); - return; - } - - d->addAttr(new FormatAttr(std::string(Format, FormatLen), - Idx.getZExtValue(), FirstArg.getZExtValue())); -} - -void Sema::HandleTransparentUnionAttribute(Decl *d, - const AttributeList *rawAttr) { - // check the attribute arguments. - if (rawAttr->getNumArgs() != 0) { - Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, - std::string("0")); - return; - } - - TypeDecl *decl = dyn_cast<TypeDecl>(d); - - if (!decl || !Context.getTypeDeclType(decl)->isUnionType()) { - Diag(rawAttr->getLoc(), diag::warn_attribute_wrong_decl_type, - "transparent_union", "union"); - return; - } - - //QualType QTy = Context.getTypeDeclType(decl); - //const RecordType *Ty = QTy->getAsUnionType(); - -// FIXME -// Ty->addAttr(new TransparentUnionAttr()); -} - -void Sema::HandleAnnotateAttribute(Decl *d, const AttributeList *rawAttr) { - // check the attribute arguments. - if (rawAttr->getNumArgs() != 1) { - Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, - std::string("1")); - return; - } - Expr *argExpr = static_cast<Expr *>(rawAttr->getArg(0)); - StringLiteral *SE = dyn_cast<StringLiteral>(argExpr); - - // Make sure that there is a string literal as the annotation's single - // argument. - if (!SE) { - Diag(rawAttr->getLoc(), diag::err_attribute_annotate_no_string); - return; - } - d->addAttr(new AnnotateAttr(std::string(SE->getStrData(), - SE->getByteLength()))); -} - -void Sema::HandleAlignedAttribute(Decl *d, const AttributeList *rawAttr) -{ - // check the attribute arguments. - if (rawAttr->getNumArgs() > 1) { - Diag(rawAttr->getLoc(), diag::err_attribute_wrong_number_arguments, - std::string("1")); - return; - } - - unsigned Align = 0; - - if (rawAttr->getNumArgs() == 0) { - // FIXME: This should be the target specific maximum alignment. - // (For now we just use 128 bits which is the maximum on X86. - Align = 128; - return; - } else { - Expr *alignmentExpr = static_cast<Expr *>(rawAttr->getArg(0)); - llvm::APSInt alignment(32); - if (!alignmentExpr->isIntegerConstantExpr(alignment, Context)) { - Diag(rawAttr->getLoc(), diag::err_attribute_argument_not_int, - "aligned", alignmentExpr->getSourceRange()); - return; - } - - Align = alignment.getZExtValue() * 8; - } - - d->addAttr(new AlignedAttr(Align)); -} |