[cfe-commits] r93118 - in /cfe/trunk: include/clang/AST/Attr.h lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/CodeGen/CodeGenTypes.cpp lib/CodeGen/CodeGenTypes.h lib/CodeGen/TargetInfo.cpp lib/CodeGen/TargetInfo.h lib/Frontend/PCHReaderDecl.cpp lib/Frontend/PCHWriter.cpp lib/Sema/Sema.cpp lib/Sema/Sema.h lib/Sema/SemaDeclAttr.cpp lib/Sema/TargetAttributesSema.cpp lib/Sema/TargetAttributesSema.h

Anton Korobeynikov asl at math.spbu.ru
Sun Jan 10 04:58:08 PST 2010


Author: asl
Date: Sun Jan 10 06:58:08 2010
New Revision: 93118

URL: http://llvm.org/viewvc/llvm-project?rev=93118&view=rev
Log:
Generalize target weirdness handling having proper layering in mind:
 1. Add helper class for sema checks for target attributes
 2. Add helper class for codegen of target attributes

As a proof-of-concept - implement msp430's 'interrupt' attribute.

Added:
    cfe/trunk/lib/CodeGen/TargetInfo.h
    cfe/trunk/lib/Sema/TargetAttributesSema.cpp
    cfe/trunk/lib/Sema/TargetAttributesSema.h
Modified:
    cfe/trunk/include/clang/AST/Attr.h
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
    cfe/trunk/lib/CodeGen/CodeGenTypes.h
    cfe/trunk/lib/CodeGen/TargetInfo.cpp
    cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp

Modified: cfe/trunk/include/clang/AST/Attr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Attr.h?rev=93118&r1=93117&r2=93118&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Attr.h (original)
+++ cfe/trunk/include/clang/AST/Attr.h Sun Jan 10 06:58:08 2010
@@ -55,8 +55,6 @@
     Cleanup,
     Const,
     Constructor,
-    DLLExport,
-    DLLImport,
     Deprecated,
     Destructor,
     FastCall,
@@ -93,7 +91,12 @@
     Visibility,
     WarnUnusedResult,
     Weak,
-    WeakImport
+    WeakImport,
+
+    FIRST_TARGET_ATTRIBUTE,
+    DLLExport,
+    DLLImport,
+    MSP430Interrupt
   };
 
 private:
@@ -456,8 +459,6 @@
   static bool classof(const VisibilityAttr *A) { return true; }
 };
 
-DEF_SIMPLE_ATTR(DLLImport);
-DEF_SIMPLE_ATTR(DLLExport);
 DEF_SIMPLE_ATTR(FastCall);
 DEF_SIMPLE_ATTR(StdCall);
 DEF_SIMPLE_ATTR(CDecl);
@@ -566,6 +567,27 @@
 DEF_SIMPLE_ATTR(Hiding);
 DEF_SIMPLE_ATTR(Override);
 
+// Target-specific attributes
+DEF_SIMPLE_ATTR(DLLImport);
+DEF_SIMPLE_ATTR(DLLExport);
+
+class MSP430InterruptAttr : public Attr {
+  unsigned Number;
+
+public:
+  MSP430InterruptAttr(unsigned n) : Attr(MSP430Interrupt), Number(n) {}
+
+  unsigned getNumber() const { return Number; }
+
+  virtual Attr *clone(ASTContext &C) const {
+    return ::new (C) MSP430InterruptAttr(Number);
+  }
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Attr *A) { return A->getKind() == MSP430Interrupt; }
+  static bool classof(const MSP430InterruptAttr *A) { return true; }
+};
+
 #undef DEF_SIMPLE_ATTR
 
 }  // end namespace clang

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=93118&r1=93117&r2=93118&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Sun Jan 10 06:58:08 2010
@@ -17,6 +17,7 @@
 #include "CGCall.h"
 #include "CGObjCRuntime.h"
 #include "Mangle.h"
+#include "TargetInfo.h"
 #include "clang/CodeGen/CodeGenOptions.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
@@ -42,8 +43,9 @@
                              Diagnostic &diags)
   : BlockModule(C, M, TD, Types, *this), Context(C),
     Features(C.getLangOptions()), CodeGenOpts(CGO), TheModule(M),
-    TheTargetData(TD), Diags(diags), Types(C, M, TD), MangleCtx(C), 
-    VtableInfo(*this), Runtime(0),
+    TheTargetData(TD), TheTargetCodeGenInfo(0), Diags(diags),
+    Types(C, M, TD, getTargetCodeGenInfo().getABIInfo()),
+    MangleCtx(C), VtableInfo(*this), Runtime(0),
     MemCpyFn(0), MemMoveFn(0), MemSetFn(0), CFConstantStringClassRef(0),
     VMContext(M.getContext()) {
 
@@ -376,6 +378,8 @@
 
   if (const SectionAttr *SA = D->getAttr<SectionAttr>())
     GV->setSection(SA->getName());
+
+  getTargetCodeGenInfo().SetTargetAttributes(D, GV, *this);
 }
 
 void CodeGenModule::SetInternalFunctionAttributes(const Decl *D,

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=93118&r1=93117&r2=93118&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Sun Jan 10 06:58:08 2010
@@ -43,6 +43,7 @@
 }
 
 namespace clang {
+  class TargetCodeGenInfo;
   class ASTContext;
   class FunctionDecl;
   class IdentifierInfo;
@@ -85,6 +86,7 @@
   const CodeGenOptions &CodeGenOpts;
   llvm::Module &TheModule;
   const llvm::TargetData &TheTargetData;
+  mutable const TargetCodeGenInfo *TheTargetCodeGenInfo;
   Diagnostic &Diags;
   CodeGenTypes Types;
   MangleContext MangleCtx;
@@ -191,6 +193,7 @@
   Diagnostic &getDiags() const { return Diags; }
   const llvm::TargetData &getTargetData() const { return TheTargetData; }
   llvm::LLVMContext &getLLVMContext() { return VMContext; }
+  const TargetCodeGenInfo &getTargetCodeGenInfo() const;
 
   /// getDeclVisibilityMode - Compute the visibility of the decl \arg D.
   LangOptions::VisibilityMode getDeclVisibilityMode(const Decl *D) const;

Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.cpp?rev=93118&r1=93117&r2=93118&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Sun Jan 10 06:58:08 2010
@@ -28,9 +28,9 @@
 using namespace CodeGen;
 
 CodeGenTypes::CodeGenTypes(ASTContext &Ctx, llvm::Module& M,
-                           const llvm::TargetData &TD)
+                           const llvm::TargetData &TD, const ABIInfo &Info)
   : Context(Ctx), Target(Ctx.Target), TheModule(M), TheTargetData(TD),
-    TheABIInfo(0) {
+    TheABIInfo(Info) {
 }
 
 CodeGenTypes::~CodeGenTypes() {
@@ -44,7 +44,6 @@
     while (I != E)
       delete &*I++;
   }
-  delete TheABIInfo;
 }
 
 /// ConvertType - Convert the specified type to its LLVM form.

Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.h?rev=93118&r1=93117&r2=93118&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.h Sun Jan 10 06:58:08 2010
@@ -85,7 +85,7 @@
   const TargetInfo &Target;
   llvm::Module& TheModule;
   const llvm::TargetData& TheTargetData;
-  mutable const ABIInfo* TheABIInfo;
+  const ABIInfo& TheABIInfo;
 
   llvm::SmallVector<std::pair<QualType,
                               llvm::OpaqueType *>, 8>  PointersToResolve;
@@ -140,13 +140,14 @@
   /// interface to convert type T into a llvm::Type.
   const llvm::Type *ConvertNewType(QualType T);
 public:
-  CodeGenTypes(ASTContext &Ctx, llvm::Module &M, const llvm::TargetData &TD);
+  CodeGenTypes(ASTContext &Ctx, llvm::Module &M, const llvm::TargetData &TD,
+               const ABIInfo &Info);
   ~CodeGenTypes();
 
   const llvm::TargetData &getTargetData() const { return TheTargetData; }
   const TargetInfo &getTarget() const { return Target; }
   ASTContext &getContext() const { return Context; }
-  const ABIInfo &getABIInfo() const;
+  const ABIInfo &getABIInfo() const { return TheABIInfo; }
   llvm::LLVMContext &getLLVMContext() { return TheModule.getContext(); }
 
   /// ConvertType - Convert type T into a llvm::Type.

Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=93118&r1=93117&r2=93118&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Sun Jan 10 06:58:08 2010
@@ -1,4 +1,4 @@
-//===---- TargetABIInfo.cpp - Encapsulate target ABI details ----*- C++ -*-===//
+//===---- TargetInfo.cpp - Encapsulate target details -----------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -12,10 +12,12 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "TargetInfo.h"
 #include "ABIInfo.h"
 #include "CodeGenFunction.h"
 #include "clang/AST/RecordLayout.h"
 #include "llvm/Type.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace clang;
@@ -50,6 +52,8 @@
   OS << ")\n";
 }
 
+TargetCodeGenInfo::~TargetCodeGenInfo() { delete Info; }
+
 static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays);
 
 /// isEmptyField - Return true iff a the field is "empty", that is it
@@ -251,6 +255,27 @@
                                  CodeGenFunction &CGF) const;
 };
 
+class DefaultTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  DefaultTargetCodeGenInfo():TargetCodeGenInfo(new DefaultABIInfo()) {};
+};
+
+llvm::Value *DefaultABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
+                                       CodeGenFunction &CGF) const {
+  return 0;
+}
+
+ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty,
+                                                ASTContext &Context,
+                                          llvm::LLVMContext &VMContext) const {
+  if (CodeGenFunction::hasAggregateLLVMType(Ty)) {
+    return ABIArgInfo::getIndirect(0);
+  } else {
+    return (Ty->isPromotableIntegerType() ?
+            ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
+  }
+}
+
 /// X86_32ABIInfo - The X86-32 ABI information.
 class X86_32ABIInfo : public ABIInfo {
   ASTContext &Context;
@@ -291,8 +316,14 @@
     : ABIInfo(), Context(Context), IsDarwinVectorABI(d),
       IsSmallStructInRegABI(p) {}
 };
-}
 
+class X86_32TargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  X86_32TargetCodeGenInfo(ASTContext &Context, bool d, bool p)
+    :TargetCodeGenInfo(new X86_32ABIInfo(Context, d, p)) {};
+};
+
+}
 
 /// shouldReturnTypeInRegister - Determine if the given type should be
 /// passed in a register (for the Darwin ABI).
@@ -585,6 +616,12 @@
   virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
                                  CodeGenFunction &CGF) const;
 };
+
+class X86_64TargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  X86_64TargetCodeGenInfo():TargetCodeGenInfo(new X86_64ABIInfo()) {};
+};
+
 }
 
 X86_64ABIInfo::Class X86_64ABIInfo::merge(Class Accum,
@@ -1389,6 +1426,11 @@
                                  CodeGenFunction &CGF) const;
 };
 
+class PIC16TargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  PIC16TargetCodeGenInfo():TargetCodeGenInfo(new PIC16ABIInfo()) {};
+};
+
 }
 
 ABIArgInfo PIC16ABIInfo::classifyReturnType(QualType RetTy,
@@ -1448,6 +1490,12 @@
                                  CodeGenFunction &CGF) const;
 };
 
+class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  ARMTargetCodeGenInfo(ARMABIInfo::ABIKind K)
+    :TargetCodeGenInfo(new ARMABIInfo(K)) {};
+};
+
 }
 
 void ARMABIInfo::computeInfo(CGFunctionInfo &FI, ASTContext &Context,
@@ -1704,6 +1752,11 @@
                                  CodeGenFunction &CGF) const;
 };
 
+class SystemZTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  SystemZTargetCodeGenInfo():TargetCodeGenInfo(new SystemZABIInfo()) {};
+};
+
 }
 
 bool SystemZABIInfo::isPromotableIntegerType(QualType Ty) const {
@@ -1757,51 +1810,79 @@
   }
 }
 
-ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty,
-                                                ASTContext &Context,
-                                          llvm::LLVMContext &VMContext) const {
-  if (CodeGenFunction::hasAggregateLLVMType(Ty)) {
-    return ABIArgInfo::getIndirect(0);
-  } else {
-    return (Ty->isPromotableIntegerType() ?
-            ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
-  }
+// MSP430 ABI Implementation
+
+namespace {
+
+class MSP430TargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  MSP430TargetCodeGenInfo():TargetCodeGenInfo(new DefaultABIInfo()) {};
+  void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
+                           CodeGen::CodeGenModule &M) const;
+};
+
 }
 
-llvm::Value *DefaultABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
-                                       CodeGenFunction &CGF) const {
-  return 0;
+void MSP430TargetCodeGenInfo::SetTargetAttributes(const Decl *D,
+                                                  llvm::GlobalValue *GV,
+                                             CodeGen::CodeGenModule &M) const {
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    if (const MSP430InterruptAttr *attr = FD->getAttr<MSP430InterruptAttr>()) {
+      // Handle 'interrupt' attribute:
+      llvm::Function *F = cast<llvm::Function>(GV);
+
+      // Step 1: Set ISR calling convention.
+      F->setCallingConv(llvm::CallingConv::MSP430_INTR);
+
+      // Step 2: Add attributes goodness.
+      F->addFnAttr(llvm::Attribute::NoInline);
+
+      // Step 3: Emit ISR vector alias.
+      unsigned Num = attr->getNumber() + 0xffe0;
+      new llvm::GlobalAlias(GV->getType(), llvm::Function::ExternalLinkage,
+                            "vector_" +
+                            llvm::LowercaseString(llvm::utohexstr(Num)),
+                            GV, &M.getModule());
+    }
+  }
 }
 
-const ABIInfo &CodeGenTypes::getABIInfo() const {
-  if (TheABIInfo)
-    return *TheABIInfo;
+const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() const {
+  if (TheTargetCodeGenInfo)
+    return *TheTargetCodeGenInfo;
 
-  // For now we just cache the ABIInfo in CodeGenTypes and don't free it.
+  // For now we just cache the TargetCodeGenInfo in CodeGenModule and don't
+  // free it.
 
   const llvm::Triple &Triple(getContext().Target.getTriple());
   switch (Triple.getArch()) {
   default:
-    return *(TheABIInfo = new DefaultABIInfo);
+    return *(TheTargetCodeGenInfo = new DefaultTargetCodeGenInfo);
 
   case llvm::Triple::arm:
   case llvm::Triple::thumb:
     // FIXME: We want to know the float calling convention as well.
     if (strcmp(getContext().Target.getABI(), "apcs-gnu") == 0)
-      return *(TheABIInfo = new ARMABIInfo(ARMABIInfo::APCS));
+      return *(TheTargetCodeGenInfo =
+               new ARMTargetCodeGenInfo(ARMABIInfo::APCS));
 
-    return *(TheABIInfo = new ARMABIInfo(ARMABIInfo::AAPCS));
+    return *(TheTargetCodeGenInfo =
+             new ARMTargetCodeGenInfo(ARMABIInfo::AAPCS));
 
   case llvm::Triple::pic16:
-    return *(TheABIInfo = new PIC16ABIInfo());
+    return *(TheTargetCodeGenInfo = new PIC16TargetCodeGenInfo());
 
   case llvm::Triple::systemz:
-    return *(TheABIInfo = new SystemZABIInfo());
+    return *(TheTargetCodeGenInfo = new SystemZTargetCodeGenInfo());
+
+  case llvm::Triple::msp430:
+    return *(TheTargetCodeGenInfo = new MSP430TargetCodeGenInfo());
 
   case llvm::Triple::x86:
     switch (Triple.getOS()) {
     case llvm::Triple::Darwin:
-      return *(TheABIInfo = new X86_32ABIInfo(Context, true, true));
+      return *(TheTargetCodeGenInfo =
+               new X86_32TargetCodeGenInfo(Context, true, true));
     case llvm::Triple::Cygwin:
     case llvm::Triple::MinGW32:
     case llvm::Triple::MinGW64:
@@ -1809,13 +1890,15 @@
     case llvm::Triple::DragonFly:
     case llvm::Triple::FreeBSD:
     case llvm::Triple::OpenBSD:
-      return *(TheABIInfo = new X86_32ABIInfo(Context, false, true));
+      return *(TheTargetCodeGenInfo =
+               new X86_32TargetCodeGenInfo(Context, false, true));
 
     default:
-      return *(TheABIInfo = new X86_32ABIInfo(Context, false, false));
+      return *(TheTargetCodeGenInfo =
+               new X86_32TargetCodeGenInfo(Context, false, false));
     }
 
   case llvm::Triple::x86_64:
-    return *(TheABIInfo = new X86_64ABIInfo());
+    return *(TheTargetCodeGenInfo = new X86_64TargetCodeGenInfo());
   }
 }

Added: cfe/trunk/lib/CodeGen/TargetInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.h?rev=93118&view=auto

==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.h (added)
+++ cfe/trunk/lib/CodeGen/TargetInfo.h Sun Jan 10 06:58:08 2010
@@ -0,0 +1,50 @@
+//===---- TargetInfo.h - Encapsulate target details -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These classes wrap the information about a call or function
+// definition used to handle ABI compliancy.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_TARGETINFO_H
+#define CLANG_CODEGEN_TARGETINFO_H
+
+namespace llvm {
+  class GlobalValue;
+}
+
+namespace clang {
+  class ABIInfo;
+  class Decl;
+
+  namespace CodeGen {
+    class CodeGenModule;
+  }
+
+  /// TargetCodeGenInfo - This class organizes various target-specific
+  /// codegeneration issues, like target-specific attributes, builtins and so
+  /// on.
+  class TargetCodeGenInfo {
+    ABIInfo *Info;
+  public:
+    // WARNING: Acquires the ownership of ABIInfo.
+    TargetCodeGenInfo(ABIInfo *info = 0):Info(info) { };
+    virtual ~TargetCodeGenInfo();
+
+    /// getABIInfo() - Returns ABI info helper for the target.
+    const ABIInfo& getABIInfo() const { return *Info; }
+
+    /// SetTargetAttributes - Provides a convenient hook to handle extra
+    /// target-specific attributes for the given global.
+    virtual void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
+                                     CodeGen::CodeGenModule &M) const { };
+  };
+}
+
+#endif // CLANG_CODEGEN_TARGETINFO_H

Modified: cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderDecl.cpp?rev=93118&r1=93117&r2=93118&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderDecl.cpp Sun Jan 10 06:58:08 2010
@@ -438,6 +438,9 @@
     bool IsInherited = Record[Idx++];
 
     switch (Kind) {
+    default:
+      assert(0 && "Unknown attribute!");
+      break;
     STRING_ATTR(Alias);
     UNSIGNED_ATTR(Aligned);
     SIMPLE_ATTR(AlwaysInline);

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=93118&r1=93117&r2=93118&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Sun Jan 10 06:58:08 2010
@@ -1739,9 +1739,12 @@
 void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
   RecordData Record;
   for (; Attr; Attr = Attr->getNext()) {
-    Record.push_back(Attr->getKind()); // FIXME: stable encoding
+    Record.push_back(Attr->getKind()); // FIXME: stable encoding, target attrs
     Record.push_back(Attr->isInherited());
     switch (Attr->getKind()) {
+    default:
+      assert(0 && "Does not support PCH writing for this attribute yet!");
+      break;
     case Attr::Alias:
       AddString(cast<AliasAttr>(Attr)->getAliasee(), Record);
       break;

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=93118&r1=93117&r2=93118&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Sun Jan 10 06:58:08 2010
@@ -13,6 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "Sema.h"
+#include "TargetAttributesSema.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/APFloat.h"
 #include "clang/AST/ASTConsumer.h"
@@ -347,7 +348,8 @@
 Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
            bool CompleteTranslationUnit,
            CodeCompleteConsumer *CodeCompleter)
-  : LangOpts(pp.getLangOptions()), PP(pp), Context(ctxt), Consumer(consumer),
+  : TheTargetAttributesSema(0),
+    LangOpts(pp.getLangOptions()), PP(pp), Context(ctxt), Consumer(consumer),
     Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
     ExternalSource(0), CodeCompleter(CodeCompleter), CurContext(0), 
     CurBlock(0), PackContext(0), ParsingDeclDepth(0),
@@ -368,6 +370,11 @@
                   ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0));
 }
 
+Sema::~Sema() {
+  if (PackContext) FreePackedContext();
+  delete TheTargetAttributesSema;
+}
+
 /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
 /// If there is already an implicit cast, merge into the existing one.
 /// If isLvalue, the result of the cast is an lvalue.

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=93118&r1=93117&r2=93118&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Sun Jan 10 06:58:08 2010
@@ -101,6 +101,7 @@
   class InitializationKind;
   class InitializationSequence;
   class VisibleDeclConsumer;
+  class TargetAttributesSema;
 
 /// BlockSemaInfo - When a block is being parsed, this contains information
 /// about the block.  It is pointed to from Sema::CurBlock.
@@ -176,6 +177,7 @@
 class Sema : public Action {
   Sema(const Sema&);           // DO NOT IMPLEMENT
   void operator=(const Sema&); // DO NOT IMPLEMENT
+  mutable const TargetAttributesSema* TheTargetAttributesSema;
 public:
   const LangOptions &LangOpts;
   Preprocessor &PP;
@@ -426,13 +428,12 @@
   Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
        bool CompleteTranslationUnit = true,
        CodeCompleteConsumer *CompletionConsumer = 0);
-  ~Sema() {
-    if (PackContext) FreePackedContext();
-  }
+  ~Sema();
 
   const LangOptions &getLangOptions() const { return LangOpts; }
   Diagnostic &getDiagnostics() const { return Diags; }
   SourceManager &getSourceManager() const { return SourceMgr; }
+  const TargetAttributesSema &getTargetAttributesSema() const;
 
   /// \brief Helper class that creates diagnostics with optional
   /// template instantiation stacks.

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=93118&r1=93117&r2=93118&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Sun Jan 10 06:58:08 2010
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "Sema.h"
+#include "TargetAttributesSema.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
@@ -1959,7 +1960,10 @@
     // Just ignore
     break;
   default:
-    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
+    // Ask target about the attribute.
+    const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
+    if (!TargetAttrs.ProcessDeclAttribute(scope, D, Attr, S))
+      S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
     break;
   }
 }

Added: cfe/trunk/lib/Sema/TargetAttributesSema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TargetAttributesSema.cpp?rev=93118&view=auto

==============================================================================
--- cfe/trunk/lib/Sema/TargetAttributesSema.cpp (added)
+++ cfe/trunk/lib/Sema/TargetAttributesSema.cpp Sun Jan 10 06:58:08 2010
@@ -0,0 +1,86 @@
+//===-- 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 "Sema.h"
+#include "TargetAttributesSema.h"
+#include "clang/Basic/TargetInfo.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 HandleMSP430InterruptAttr(Decl *d,
+                                      const AttributeList &Attr, Sema &S) {
+    // Check the attribute arguments.
+    if (Attr.getNumArgs() != 1) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+      return;
+    }
+
+    // FIXME: Check for decl - it should be void ()(void).
+
+    Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0));
+    llvm::APSInt NumParams(32);
+    if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
+        << "interrupt" << NumParamsExpr->getSourceRange();
+      return;
+    }
+
+    unsigned Num = NumParams.getLimitedValue(255);
+    if ((Num & 1) || Num > 30) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds)
+        << "interrupt" << (int)NumParams.getSExtValue()
+        << NumParamsExpr->getSourceRange();
+      return;
+    }
+
+    d->addAttr(::new (S.Context) MSP430InterruptAttr(Num));
+    d->addAttr(::new (S.Context) UsedAttr());
+  }
+
+namespace {
+  class MSP430AttributesSema : public TargetAttributesSema {
+  public:
+    MSP430AttributesSema() { }
+    bool ProcessDeclAttribute(Scope *scope, Decl *D,
+                              const AttributeList &Attr, Sema &S) const {
+      if (Attr.getName()->getName() == "interrupt") {
+        HandleMSP430InterruptAttr(D, Attr, S);
+        return true;
+      }
+      return false;
+    }
+  };
+}
+
+const TargetAttributesSema &Sema::getTargetAttributesSema() const {
+  if (TheTargetAttributesSema)
+    return *TheTargetAttributesSema;
+
+  const llvm::Triple &Triple(Context.Target.getTriple());
+  switch (Triple.getArch()) {
+  default:
+    return *(TheTargetAttributesSema = new TargetAttributesSema);
+
+  case llvm::Triple::msp430:
+    return *(TheTargetAttributesSema = new MSP430AttributesSema);
+  }
+}
+

Added: cfe/trunk/lib/Sema/TargetAttributesSema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TargetAttributesSema.h?rev=93118&view=auto

==============================================================================
--- cfe/trunk/lib/Sema/TargetAttributesSema.h (added)
+++ cfe/trunk/lib/Sema/TargetAttributesSema.h Sun Jan 10 06:58:08 2010
@@ -0,0 +1,27 @@
+//===--- 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 Attr;
+  class Sema;
+
+  class TargetAttributesSema {
+  public:
+    virtual ~TargetAttributesSema();
+    virtual bool ProcessDeclAttribute(Scope *scope, Decl *D,
+                                      const AttributeList &Attr, Sema &S) const;
+  };
+}
+
+#endif





More information about the cfe-commits mailing list