]> granicus.if.org Git - clang/commitdiff
Generate code for annotation attributes.
authorNate Begeman <natebegeman@mac.com>
Sat, 19 Apr 2008 04:17:09 +0000 (04:17 +0000)
committerNate Begeman <natebegeman@mac.com>
Sat, 19 Apr 2008 04:17:09 +0000 (04:17 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49951 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGDecl.cpp
lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/CodeGenModule.h

index e186bb69ebf01234a015201016523869dd714caf..df5882c2172b51a90325a438c18422e16e368d49 100644 (file)
@@ -14,6 +14,7 @@
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
 #include "clang/AST/AST.h"
+#include "clang/Basic/SourceManager.h"
 #include "llvm/GlobalVariable.h"
 #include "llvm/Type.h"
 using namespace clang;
@@ -82,19 +83,26 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D) {
   }
 
   assert(Init && "Unable to create initialiser for static decl");
-  
+
   std::string ContextName;
   if (const FunctionDecl * FD = dyn_cast<FunctionDecl>(CurFuncDecl))
     ContextName = FD->getName();
   else
     assert(0 && "Unknown context for block var decl"); // FIXME Handle objc.
-  
-  DMEntry = 
-    new llvm::GlobalVariable(LTy, false, 
-                            llvm::GlobalValue::InternalLinkage,
+
+  llvm::GlobalValue *GV = 
+    new llvm::GlobalVariable(LTy, false, llvm::GlobalValue::InternalLinkage,
                              Init, ContextName + "." + D.getName(),
-                             &CGM.getModule(), 0,
-                             Ty.getAddressSpace());
+                             &CGM.getModule(), 0, Ty.getAddressSpace());
+
+  if (const AnnotateAttr *AA = D.getAttr<AnnotateAttr>()) {
+    SourceManager &SM = CGM.getContext().getSourceManager();
+    llvm::Constant *Ann =
+      CGM.EmitAnnotateAttr(GV, AA, SM.getLogicalLineNumber(D.getLocation()));
+    CGM.AddAnnotation(Ann);
+  }
+
+  DMEntry = GV;
 }
   
 /// EmitLocalBlockVarDecl - Emit code and set up an entry in LocalDeclMap for a
index a5a51b19c7961ce6bb529e8157a677e02b2ae750..da38698ab61382c92d59e8a0f10bc62003fc3f0a 100644 (file)
@@ -17,6 +17,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/CallingConv.h"
 #include "llvm/Constants.h"
@@ -305,6 +306,50 @@ llvm::Constant *CodeGenModule::EmitGlobalInit(const Expr *Expr) {
   return EmitConstantExpr(Expr);
 }
 
+/// EmitAnnotateAttr - Generate the llvm::ConstantStruct which contains the 
+/// annotation information for a given GlobalValue.  The annotation struct is
+/// {i8 *, i8 *, i8 *, i32}.  The first field is a constant expression, the 
+/// GlobalValue being annotated.  The second filed is thee constant string 
+/// created from the AnnotateAttr's annotation.  The third field is a constant 
+/// string containing the name of the translation unit.  The fourth field is
+/// the line number in the file of the annotated value declaration.
+///
+/// FIXME: this does not unique the annotation string constants, as llvm-gcc
+///        appears to.
+///
+llvm::Constant *CodeGenModule::EmitAnnotateAttr(llvm::GlobalValue *GV, 
+                                                const AnnotateAttr *AA,
+                                                unsigned LineNo) {
+  llvm::Module *M = &getModule();
+
+  // get [N x i8] constants for the annotation string, and the filename string
+  // which are the 2nd and 3rd elements of the global annotation structure.
+  const llvm::Type *SBP = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
+  llvm::Constant *anno = llvm::ConstantArray::get(AA->getAnnotation(), true);
+  llvm::Constant *unit = llvm::ConstantArray::get(M->getModuleIdentifier(),
+                                                  true);
+
+  // Get the two global values corresponding to the ConstantArrays we just
+  // created to hold the bytes of the strings.
+  llvm::GlobalValue *annoGV = 
+  new llvm::GlobalVariable(anno->getType(), false,
+                           llvm::GlobalValue::InternalLinkage, anno,
+                           GV->getName() + ".str", M);
+  // translation unit name string, emitted into the llvm.metadata section.
+  llvm::GlobalValue *unitGV =
+  new llvm::GlobalVariable(unit->getType(), false,
+                           llvm::GlobalValue::InternalLinkage, unit, ".str", M);
+
+  // Create the ConstantStruct that is the global annotion.
+  llvm::Constant *Fields[4] = {
+    llvm::ConstantExpr::getBitCast(GV, SBP),
+    llvm::ConstantExpr::getBitCast(annoGV, SBP),
+    llvm::ConstantExpr::getBitCast(unitGV, SBP),
+    llvm::ConstantInt::get(llvm::Type::Int32Ty, LineNo)
+  };
+  return llvm::ConstantStruct::get(Fields, 4, false);
+}
+
 void CodeGenModule::EmitGlobalVar(const VarDecl *D) {
   // If this is just a forward declaration of the variable, don't emit it now,
   // allow it to be emitted lazily on its first use.
@@ -329,6 +374,12 @@ void CodeGenModule::EmitGlobalVar(const VarDecl *D) {
   if (!Init)
     Init = EmitGlobalInit(D->getInit());
 
+  if (const AnnotateAttr *AA = D->getAttr<AnnotateAttr>()) {
+    SourceManager &SM = Context.getSourceManager();
+    AddAnnotation(EmitAnnotateAttr(GV, AA,
+                                   SM.getLogicalLineNumber(D->getLocation())));
+  }
+
   assert(GV->getType()->getElementType() == Init->getType() &&
          "Initializer codegen type mismatch!");
   GV->setInitializer(Init);
index e192e9913ee741c950867adc531094900280857d..d40e35e00ce71e47bef8eb2df1b589daeb625c4a 100644 (file)
@@ -23,7 +23,7 @@ namespace llvm {
   class Module;
   class Constant;
   class Function;
-  class GlobalVariable;
+  class GlobalValue;
   class TargetData;
 }
 
@@ -39,6 +39,7 @@ namespace clang {
   class TypeDecl;
   struct LangOptions;
   class Diagnostic;
+  class AnnotateAttr;
     
 namespace CodeGen {
 
@@ -110,6 +111,8 @@ public:
   void UpdateCompletedType(const TagDecl *D);
   llvm::Constant *EmitGlobalInit(const Expr *E);
   llvm::Constant *EmitConstantExpr(const Expr *E, CodeGenFunction *CGF = 0);
+  llvm::Constant *EmitAnnotateAttr(llvm::GlobalValue *GV,
+                                   const AnnotateAttr *AA, unsigned LineNo);
     
   /// WarnUnsupported - Print out a warning that codegen doesn't support the
   /// specified stmt yet.