summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorAaron Ballman <aaron@aaronballman.com>2014-01-09 22:48:32 +0000
committerAaron Ballman <aaron@aaronballman.com>2014-01-09 22:48:32 +0000
commitab7691c4ce72faf49e14fe715ec608f236742e24 (patch)
tree2d22bb6654b8411d8763c0cfb9b18307ec2e5604 /clang/lib/Sema
parenta3570186b2385cc6aaeb4babeef94add5ba37ab4 (diff)
downloadbcm5719-llvm-ab7691c4ce72faf49e14fe715ec608f236742e24.tar.gz
bcm5719-llvm-ab7691c4ce72faf49e14fe715ec608f236742e24.zip
Removing the notion of TargetAttributesSema and replacing it with one where the parsed attributes are responsible for knowing their target-specific nature, instead of letting Sema figure it out. This is necessary so that __has_attribute can eventually determine whether a parsed attribute applies to the given target or not.
llvm-svn: 198896
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/AttributeList.cpp15
-rw-r--r--clang/lib/Sema/CMakeLists.txt1
-rw-r--r--clang/lib/Sema/Sema.cpp4
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp235
-rw-r--r--clang/lib/Sema/SemaStmtAttr.cpp1
-rw-r--r--clang/lib/Sema/TargetAttributesSema.cpp295
-rw-r--r--clang/lib/Sema/TargetAttributesSema.h27
7 files changed, 219 insertions, 359 deletions
diff --git a/clang/lib/Sema/AttributeList.cpp b/clang/lib/Sema/AttributeList.cpp
index c079c30382c..58a3e23c1b0 100644
--- a/clang/lib/Sema/AttributeList.cpp
+++ b/clang/lib/Sema/AttributeList.cpp
@@ -156,10 +156,13 @@ struct ParsedAttrInfo {
unsigned NumArgs : 4;
unsigned OptArgs : 4;
unsigned HasCustomParsing : 1;
+ unsigned IsTargetSpecific : 1;
+ unsigned IsType : 1;
bool (*DiagAppertainsToDecl)(Sema &S, const AttributeList &Attr,
const Decl *);
bool (*DiagLangOpts)(Sema &S, const AttributeList &Attr);
+ bool (*ExistsInTarget)(llvm::Triple T);
};
namespace {
@@ -189,3 +192,15 @@ bool AttributeList::diagnoseAppertainsTo(Sema &S, const Decl *D) const {
bool AttributeList::diagnoseLangOpts(Sema &S) const {
return getInfo(*this).DiagLangOpts(S, *this);
}
+
+bool AttributeList::isTargetSpecificAttr() const {
+ return getInfo(*this).IsTargetSpecific;
+}
+
+bool AttributeList::isTypeAttr() const {
+ return getInfo(*this).IsType;
+}
+
+bool AttributeList::existsInTarget(llvm::Triple T) const {
+ return getInfo(*this).ExistsInTarget(T);
+}
diff --git a/clang/lib/Sema/CMakeLists.txt b/clang/lib/Sema/CMakeLists.txt
index c4ebeb59407..75702e1d8b2 100644
--- a/clang/lib/Sema/CMakeLists.txt
+++ b/clang/lib/Sema/CMakeLists.txt
@@ -47,7 +47,6 @@ add_clang_library(clangSema
SemaTemplateInstantiateDecl.cpp
SemaTemplateVariadic.cpp
SemaType.cpp
- TargetAttributesSema.cpp
TypeLocBuilder.cpp
)
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 1c748f61e06..c824921a4f1 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -13,7 +13,6 @@
//===----------------------------------------------------------------------===//
#include "clang/Sema/SemaInternal.h"
-#include "TargetAttributesSema.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/DeclCXX.h"
@@ -70,7 +69,7 @@ void Sema::ActOnTranslationUnitScope(Scope *S) {
Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
TranslationUnitKind TUKind,
CodeCompleteConsumer *CodeCompleter)
- : TheTargetAttributesSema(0), ExternalSource(0),
+ : ExternalSource(0),
isMultiplexExternalSource(false), FPFeatures(pp.getLangOpts()),
LangOpts(pp.getLangOpts()), PP(pp), Context(ctxt), Consumer(consumer),
Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
@@ -209,7 +208,6 @@ Sema::~Sema() {
delete I->second;
if (PackContext) FreePackedContext();
if (VisContext) FreeVisContext();
- delete TheTargetAttributesSema;
MSStructPragmaOn = false;
// Kill all the active scopes.
for (unsigned I = 1, E = FunctionScopes.size(); I != E; ++I)
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 23649c66940..945525bdd54 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "clang/Sema/SemaInternal.h"
-#include "TargetAttributesSema.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclCXX.h"
@@ -205,7 +204,6 @@ static bool checkAttributeNumArgs(Sema &S, const AttributeList &Attr,
return true;
}
-
/// \brief Check if the attribute has at least as many args as Num. May
/// output an error.
static bool checkAttributeAtLeastNumArgs(Sema &S, const AttributeList &Attr,
@@ -3174,8 +3172,7 @@ bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
return true;
}
- // TODO: diagnose uses of these conventions on the wrong target. Or, better
- // move to TargetAttributesSema one day.
+ // TODO: diagnose uses of these conventions on the wrong target.
switch (attr.getKind()) {
case AttributeList::AT_CDecl: CC = CC_C; break;
case AttributeList::AT_FastCall: CC = CC_X86FastCall; break;
@@ -3712,6 +3709,179 @@ static void handleUuidAttr(Sema &S, Decl *D, const AttributeList &Attr) {
Attr.getAttributeSpellingListIndex()));
}
+static void handleARMInterruptAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
+ // Check the attribute arguments.
+ if (Attr.getNumArgs() > 1) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments)
+ << Attr.getName() << 1;
+ return;
+ }
+
+ StringRef Str;
+ SourceLocation ArgLoc;
+
+ if (Attr.getNumArgs() == 0)
+ Str = "";
+ else if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &ArgLoc))
+ return;
+
+ ARMInterruptAttr::InterruptType Kind;
+ if (!ARMInterruptAttr::ConvertStrToInterruptType(Str, Kind)) {
+ S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
+ << Attr.getName() << Str << ArgLoc;
+ return;
+ }
+
+ unsigned Index = Attr.getAttributeSpellingListIndex();
+ D->addAttr(::new (S.Context)
+ ARMInterruptAttr(Attr.getLoc(), S.Context, Kind, Index));
+}
+
+static void handleMSP430InterruptAttr(Sema &S, Decl *D,
+ const AttributeList &Attr) {
+ if (!checkAttributeNumArgs(S, Attr, 1))
+ return;
+
+ if (!Attr.isArgExpr(0)) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << Attr.getName()
+ << AANT_ArgumentIntegerConstant;
+ return;
+ }
+
+ // FIXME: Check for decl - it should be void ()(void).
+
+ Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArgAsExpr(0));
+ llvm::APSInt NumParams(32);
+ if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
+ << Attr.getName() << AANT_ArgumentIntegerConstant
+ << NumParamsExpr->getSourceRange();
+ return;
+ }
+
+ unsigned Num = NumParams.getLimitedValue(255);
+ if ((Num & 1) || Num > 30) {
+ S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
+ << Attr.getName() << (int)NumParams.getSExtValue()
+ << NumParamsExpr->getSourceRange();
+ return;
+ }
+
+ D->addAttr(::new (S.Context) MSP430InterruptAttr(Attr.getLoc(), S.Context, Num));
+ D->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
+}
+
+static void handleInterruptAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+ // Dispatch the interrupt attribute based on the current target.
+ if (S.Context.getTargetInfo().getTriple().getArch() == llvm::Triple::msp430)
+ handleMSP430InterruptAttr(S, D, Attr);
+ else
+ handleARMInterruptAttr(S, D, Attr);
+}
+
+static void handleX86ForceAlignArgPointerAttr(Sema &S, Decl *D,
+ const AttributeList& Attr) {
+ // If we try to apply it to a function pointer, don't warn, but don't
+ // do anything, either. It doesn't matter anyway, because there's nothing
+ // special about calling a force_align_arg_pointer function.
+ ValueDecl *VD = dyn_cast<ValueDecl>(D);
+ if (VD && VD->getType()->isFunctionPointerType())
+ return;
+ // Also don't warn on function pointer typedefs.
+ TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
+ if (TD && (TD->getUnderlyingType()->isFunctionPointerType() ||
+ TD->getUnderlyingType()->isFunctionType()))
+ return;
+ // Attribute can only be applied to function types.
+ if (!isa<FunctionDecl>(D)) {
+ S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+ << Attr.getName() << /* function */0;
+ return;
+ }
+
+ D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr(Attr.getRange(),
+ S.Context));
+}
+
+DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D, SourceRange Range,
+ unsigned AttrSpellingListIndex) {
+ if (D->hasAttr<DLLExportAttr>()) {
+ Diag(Range.getBegin(), diag::warn_attribute_ignored) << "dllimport";
+ return NULL;
+ }
+
+ if (D->hasAttr<DLLImportAttr>())
+ return NULL;
+
+ if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (VD->hasDefinition()) {
+ // dllimport cannot be applied to definitions.
+ Diag(D->getLocation(), diag::warn_attribute_invalid_on_definition)
+ << "dllimport";
+ return NULL;
+ }
+ }
+
+ return ::new (Context)DLLImportAttr(Range, Context,
+ AttrSpellingListIndex);
+}
+
+static void handleDLLImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+ // Attribute can be applied only to functions or variables.
+ FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
+ if (!FD && !isa<VarDecl>(D)) {
+ // Apparently Visual C++ thinks it is okay to not emit a warning
+ // in this case, so only emit a warning when -fms-extensions is not
+ // specified.
+ if (!S.getLangOpts().MicrosoftExt)
+ S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
+ << Attr.getName() << 2 /*variable and function*/;
+ return;
+ }
+
+ // Currently, the dllimport attribute is ignored for inlined functions.
+ // Warning is emitted.
+ if (FD && FD->isInlineSpecified()) {
+ S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
+ return;
+ }
+
+ unsigned Index = Attr.getAttributeSpellingListIndex();
+ DLLImportAttr *NewAttr = S.mergeDLLImportAttr(D, Attr.getRange(), Index);
+ if (NewAttr)
+ D->addAttr(NewAttr);
+}
+
+DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D, SourceRange Range,
+ unsigned AttrSpellingListIndex) {
+ if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) {
+ Diag(Import->getLocation(), diag::warn_attribute_ignored) << "dllimport";
+ D->dropAttr<DLLImportAttr>();
+ }
+
+ if (D->hasAttr<DLLExportAttr>())
+ return NULL;
+
+ return ::new (Context)DLLExportAttr(Range, Context,
+ AttrSpellingListIndex);
+}
+
+static void handleDLLExportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+ // Currently, the dllexport attribute is ignored for inlined functions, unless
+ // the -fkeep-inline-functions flag has been used. Warning is emitted;
+ if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isInlineSpecified()) {
+ // FIXME: ... unless the -fkeep-inline-functions flag has been used.
+ S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
+ return;
+ }
+
+ unsigned Index = Attr.getAttributeSpellingListIndex();
+ DLLExportAttr *NewAttr = S.mergeDLLExportAttr(D, Attr.getRange(), Index);
+ if (NewAttr)
+ D->addAttr(NewAttr);
+}
+
/// Handles semantic checking for features that are common to all attributes,
/// such as checking whether a parameter was properly specified, or the correct
/// number of arguments were passed, etc.
@@ -3723,8 +3893,7 @@ static bool handleCommonAttributeFeatures(Sema &S, Scope *scope, Decl *D,
// We also bail on unknown and ignored attributes because those are handled
// as part of the target-specific handling logic.
if (Attr.hasCustomParsing() ||
- Attr.getKind() == AttributeList::UnknownAttribute ||
- Attr.getKind() == AttributeList::IgnoredAttribute)
+ Attr.getKind() == AttributeList::UnknownAttribute)
return false;
// Check whether the attribute requires specific language extensions to be
@@ -3755,7 +3924,7 @@ static bool handleCommonAttributeFeatures(Sema &S, Scope *scope, Decl *D,
static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
const AttributeList &Attr,
bool IncludeCXX11Attributes) {
- if (Attr.isInvalid())
+ if (Attr.isInvalid() || Attr.getKind() == AttributeList::IgnoredAttribute)
return;
// Ignore C++11 attributes on declarator chunks: they appertain to the type
@@ -3763,28 +3932,42 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
if (Attr.isCXX11Attribute() && !IncludeCXX11Attributes)
return;
+ // Unknown attributes are automatically warned on. Target-specific attributes
+ // which do not apply to the current target architecture are treated as
+ // though they were unknown attributes.
+ if (Attr.getKind() == AttributeList::UnknownAttribute ||
+ !Attr.existsInTarget(S.Context.getTargetInfo().getTriple())) {
+ S.Diag(Attr.getLoc(), Attr.isDeclspecAttribute() ?
+ diag::warn_unhandled_ms_attribute_ignored :
+ diag::warn_unknown_attribute_ignored) << Attr.getName();
+ return;
+ }
+
if (handleCommonAttributeFeatures(S, scope, D, Attr))
return;
switch (Attr.getKind()) {
+ default:
+ // Type attributes are handled elsewhere; silently move on.
+ assert(Attr.isTypeAttr() && "Non-type attribute not handled");
+ break;
+ case AttributeList::AT_Interrupt:
+ handleInterruptAttr(S, D, Attr); break;
+ case AttributeList::AT_X86ForceAlignArgPointer:
+ handleX86ForceAlignArgPointerAttr(S, D, Attr); break;
+ case AttributeList::AT_DLLExport:
+ handleDLLExportAttr(S, D, Attr); break;
+ case AttributeList::AT_DLLImport:
+ handleDLLImportAttr(S, D, Attr); break;
+ case AttributeList::AT_Mips16:
+ handleSimpleAttribute<Mips16Attr>(S, D, Attr); break;
+ case AttributeList::AT_NoMips16:
+ handleSimpleAttribute<NoMips16Attr>(S, D, Attr); break;
case AttributeList::AT_IBAction:
handleSimpleAttribute<IBActionAttr>(S, D, Attr); break;
case AttributeList::AT_IBOutlet: handleIBOutlet(S, D, Attr); break;
case AttributeList::AT_IBOutletCollection:
handleIBOutletCollection(S, D, Attr); break;
- case AttributeList::AT_AddressSpace:
- case AttributeList::AT_ObjCGC:
- case AttributeList::AT_VectorSize:
- case AttributeList::AT_NeonVectorType:
- case AttributeList::AT_NeonPolyVectorType:
- case AttributeList::AT_Ptr32:
- case AttributeList::AT_Ptr64:
- case AttributeList::AT_SPtr:
- case AttributeList::AT_UPtr:
- case AttributeList::AT_Regparm:
- // Ignore these, these are type attributes, handled by
- // ProcessTypeAttributes.
- break;
case AttributeList::AT_Alias: handleAliasAttr (S, D, Attr); break;
case AttributeList::AT_Aligned: handleAlignedAttr (S, D, Attr); break;
case AttributeList::AT_AlwaysInline:
@@ -3946,9 +4129,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case AttributeList::AT_NoDebug: handleNoDebugAttr (S, D, Attr); break;
case AttributeList::AT_NoInline:
handleSimpleAttribute<NoInlineAttr>(S, D, Attr); break;
- case AttributeList::IgnoredAttribute:
- // Just ignore
- break;
case AttributeList::AT_NoInstrumentFunction: // Interacts with -pg.
handleSimpleAttribute<NoInstrumentFunctionAttr>(S, D, Attr); break;
case AttributeList::AT_StdCall:
@@ -4078,15 +4258,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case AttributeList::AT_TypeTagForDatatype:
handleTypeTagForDatatypeAttr(S, D, Attr);
break;
-
- default:
- // Ask target about the attribute.
- const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
- if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
- S.Diag(Attr.getLoc(), Attr.isDeclspecAttribute() ?
- diag::warn_unhandled_ms_attribute_ignored :
- diag::warn_unknown_attribute_ignored) << Attr.getName();
- break;
}
}
diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp
index eb0188a0db3..80d203e3f5b 100644
--- a/clang/lib/Sema/SemaStmtAttr.cpp
+++ b/clang/lib/Sema/SemaStmtAttr.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "clang/Sema/SemaInternal.h"
-#include "TargetAttributesSema.h"
#include "clang/AST/ASTContext.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
diff --git a/clang/lib/Sema/TargetAttributesSema.cpp b/clang/lib/Sema/TargetAttributesSema.cpp
deleted file mode 100644
index b70b15c37b2..00000000000
--- a/clang/lib/Sema/TargetAttributesSema.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-//===-- TargetAttributesSema.cpp - Encapsulate target attributes-*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains semantic analysis implementation for target-specific
-// attributes.
-//
-//===----------------------------------------------------------------------===//
-
-#include "TargetAttributesSema.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/Sema/SemaInternal.h"
-#include "llvm/ADT/Triple.h"
-
-using namespace clang;
-
-TargetAttributesSema::~TargetAttributesSema() {}
-bool TargetAttributesSema::ProcessDeclAttribute(Scope *scope, Decl *D,
- const AttributeList &Attr, Sema &S) const {
- return false;
-}
-
-static void HandleARMInterruptAttr(Decl *d,
- const AttributeList &Attr, Sema &S) {
- // Check the attribute arguments.
- if (Attr.getNumArgs() > 1) {
- S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments)
- << Attr.getName() << 1;
- return;
- }
-
- StringRef Str;
- SourceLocation ArgLoc;
-
- if (Attr.getNumArgs() == 0)
- Str = "";
- else if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &ArgLoc))
- return;
-
- ARMInterruptAttr::InterruptType Kind;
- if (!ARMInterruptAttr::ConvertStrToInterruptType(Str, Kind)) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
- << Attr.getName() << Str << ArgLoc;
- return;
- }
-
- unsigned Index = Attr.getAttributeSpellingListIndex();
- d->addAttr(::new (S.Context)
- ARMInterruptAttr(Attr.getLoc(), S.Context, Kind, Index));
-}
-
-namespace {
- class ARMAttributesSema : public TargetAttributesSema {
- public:
- ARMAttributesSema() { }
- bool ProcessDeclAttribute(Scope *scope, Decl *D,
- const AttributeList &Attr, Sema &S) const {
- if (Attr.getKind() == AttributeList::AT_Interrupt) {
- HandleARMInterruptAttr(D, Attr, S);
- return true;
- }
- return false;
- }
- };
-}
-
-static void HandleMSP430InterruptAttr(Decl *d,
- const AttributeList &Attr, Sema &S) {
- if (Attr.getNumArgs() != 1) {
- S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
- << Attr.getName() << 1;
- return;
- }
-
- if (!Attr.isArgExpr(0)) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << Attr.getName()
- << AANT_ArgumentIntegerConstant;
- return;
- }
-
- // FIXME: Check for decl - it should be void ()(void).
- Expr *NumParamsExpr = Attr.getArgAsExpr(0);
- llvm::APSInt NumParams(32);
- if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
- << Attr.getName() << AANT_ArgumentIntegerConstant
- << NumParamsExpr->getSourceRange();
- return;
- }
-
- unsigned Num = NumParams.getLimitedValue(255);
- if ((Num & 1) || Num > 30) {
- S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
- << Attr.getName() << (int)NumParams.getSExtValue()
- << NumParamsExpr->getSourceRange();
- return;
- }
-
- d->addAttr(::new (S.Context) MSP430InterruptAttr(Attr.getLoc(), S.Context, Num));
- d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
-}
-
-namespace {
- class MSP430AttributesSema : public TargetAttributesSema {
- public:
- MSP430AttributesSema() { }
- bool ProcessDeclAttribute(Scope *scope, Decl *D,
- const AttributeList &Attr, Sema &S) const {
- if (Attr.getKind() == AttributeList::AT_Interrupt) {
- HandleMSP430InterruptAttr(D, Attr, S);
- return true;
- }
- return false;
- }
- };
-}
-
-static void HandleX86ForceAlignArgPointerAttr(Decl *D,
- const AttributeList& Attr,
- Sema &S) {
- // If we try to apply it to a function pointer, don't warn, but don't
- // do anything, either. It doesn't matter anyway, because there's nothing
- // special about calling a force_align_arg_pointer function.
- ValueDecl *VD = dyn_cast<ValueDecl>(D);
- if (VD && VD->getType()->isFunctionPointerType())
- return;
- // Also don't warn on function pointer typedefs.
- TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
- if (TD && (TD->getUnderlyingType()->isFunctionPointerType() ||
- TD->getUnderlyingType()->isFunctionType()))
- return;
- // Attribute can only be applied to function types.
- if (!isa<FunctionDecl>(D)) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << Attr.getName() << /* function */0;
- return;
- }
-
- D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr(Attr.getRange(),
- S.Context));
-}
-
-DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D, SourceRange Range,
- unsigned AttrSpellingListIndex) {
- if (D->hasAttr<DLLExportAttr>()) {
- Diag(Range.getBegin(), diag::warn_attribute_ignored) << "dllimport";
- return NULL;
- }
-
- if (D->hasAttr<DLLImportAttr>())
- return NULL;
-
- if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
- if (VD->hasDefinition()) {
- // dllimport cannot be applied to definitions.
- Diag(D->getLocation(), diag::warn_attribute_invalid_on_definition)
- << "dllimport";
- return NULL;
- }
- }
-
- return ::new (Context) DLLImportAttr(Range, Context,
- AttrSpellingListIndex);
-}
-
-static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
- // Attribute can be applied only to functions or variables.
- FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
- if (!FD && !isa<VarDecl>(D)) {
- // Apparently Visual C++ thinks it is okay to not emit a warning
- // in this case, so only emit a warning when -fms-extensions is not
- // specified.
- if (!S.getLangOpts().MicrosoftExt)
- S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << Attr.getName() << 2 /*variable and function*/;
- return;
- }
-
- // Currently, the dllimport attribute is ignored for inlined functions.
- // Warning is emitted.
- if (FD && FD->isInlineSpecified()) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
- return;
- }
-
- unsigned Index = Attr.getAttributeSpellingListIndex();
- DLLImportAttr *NewAttr = S.mergeDLLImportAttr(D, Attr.getRange(), Index);
- if (NewAttr)
- D->addAttr(NewAttr);
-}
-
-DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D, SourceRange Range,
- unsigned AttrSpellingListIndex) {
- if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) {
- Diag(Import->getLocation(), diag::warn_attribute_ignored) << "dllimport";
- D->dropAttr<DLLImportAttr>();
- }
-
- if (D->hasAttr<DLLExportAttr>())
- return NULL;
-
- return ::new (Context) DLLExportAttr(Range, Context,
- AttrSpellingListIndex);
-}
-
-static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
- // Currently, the dllexport attribute is ignored for inlined functions, unless
- // the -fkeep-inline-functions flag has been used. Warning is emitted;
- if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isInlineSpecified()) {
- // FIXME: ... unless the -fkeep-inline-functions flag has been used.
- S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
- return;
- }
-
- unsigned Index = Attr.getAttributeSpellingListIndex();
- DLLExportAttr *NewAttr = S.mergeDLLExportAttr(D, Attr.getRange(), Index);
- if (NewAttr)
- D->addAttr(NewAttr);
-}
-
-namespace {
- class X86AttributesSema : public TargetAttributesSema {
- public:
- X86AttributesSema() { }
- bool ProcessDeclAttribute(Scope *scope, Decl *D,
- const AttributeList &Attr, Sema &S) const {
- const llvm::Triple &Triple(S.Context.getTargetInfo().getTriple());
- if (Triple.getOS() == llvm::Triple::Win32 ||
- Triple.getOS() == llvm::Triple::MinGW32) {
- switch (Attr.getKind()) {
- case AttributeList::AT_DLLImport: HandleDLLImportAttr(D, Attr, S);
- return true;
- case AttributeList::AT_DLLExport: HandleDLLExportAttr(D, Attr, S);
- return true;
- default: break;
- }
- }
- if (Triple.getArch() != llvm::Triple::x86_64 &&
- (Attr.getName()->getName() == "force_align_arg_pointer" ||
- Attr.getName()->getName() == "__force_align_arg_pointer__")) {
- HandleX86ForceAlignArgPointerAttr(D, Attr, S);
- return true;
- }
- return false;
- }
- };
-}
-
-namespace {
- class MipsAttributesSema : public TargetAttributesSema {
- public:
- MipsAttributesSema() { }
- bool ProcessDeclAttribute(Scope *scope, Decl *D, const AttributeList &Attr,
- Sema &S) const {
- if (Attr.getKind() == AttributeList::AT_Mips16) {
- D->addAttr(::new (S.Context) Mips16Attr(Attr.getRange(), S.Context,
- Attr.getAttributeSpellingListIndex()));
- return true;
- } else if (Attr.getKind() == AttributeList::AT_NoMips16) {
- D->addAttr(::new (S.Context) NoMips16Attr(Attr.getRange(), S.Context,
- Attr.getAttributeSpellingListIndex()));
- return true;
- }
- return false;
- }
- };
-}
-
-const TargetAttributesSema &Sema::getTargetAttributesSema() const {
- if (TheTargetAttributesSema)
- return *TheTargetAttributesSema;
-
- const llvm::Triple &Triple(Context.getTargetInfo().getTriple());
- switch (Triple.getArch()) {
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- return *(TheTargetAttributesSema = new ARMAttributesSema);
- case llvm::Triple::msp430:
- return *(TheTargetAttributesSema = new MSP430AttributesSema);
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- return *(TheTargetAttributesSema = new X86AttributesSema);
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- return *(TheTargetAttributesSema = new MipsAttributesSema);
- default:
- return *(TheTargetAttributesSema = new TargetAttributesSema);
- }
-}
diff --git a/clang/lib/Sema/TargetAttributesSema.h b/clang/lib/Sema/TargetAttributesSema.h
deleted file mode 100644
index 410c900222f..00000000000
--- a/clang/lib/Sema/TargetAttributesSema.h
+++ /dev/null
@@ -1,27 +0,0 @@
-//===--- TargetAttributesSema.h - Semantic Analysis For Target Attributes -===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CLANG_SEMA_TARGETSEMA_H
-#define CLANG_SEMA_TARGETSEMA_H
-
-namespace clang {
- class Scope;
- class Decl;
- class AttributeList;
- class Sema;
-
- class TargetAttributesSema {
- public:
- virtual ~TargetAttributesSema();
- virtual bool ProcessDeclAttribute(Scope *scope, Decl *D,
- const AttributeList &Attr, Sema &S) const;
- };
-}
-
-#endif
OpenPOWER on IntegriCloud