[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/PCHR

Daniel Dunbar daniel at zuster.org
Mon Jan 11 19:18:56 PST 2010


Hi Anton,

On Sun, Jan 10, 2010 at 4:58 AM, Anton Korobeynikov <asl at math.spbu.ru> wrote:
> 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
>   };

This should be FIRST_TARGET_ATTRIBUTE=DLLExport, if the name is to be believed.

>
>  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"

See comment below.

>  #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)),

Please use a raw_ostream & SmallString instead of adding a dependency
on StringExtras.

> +                            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;

This is bad, this will make it easy for us to miss missing PCH support
when adding attributes in the future. Please remove the default and
just add the individual enums which would be warned about.

>     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;

Are you planning on adding target attribute PCH support?

 - Daniel

>     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());
> +  }

Please add a test case for the attribute checking.

> +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
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>




More information about the cfe-commits mailing list