diff options
author | Nate Begeman <natebegeman@mac.com> | 2008-04-19 04:17:09 +0000 |
---|---|---|
committer | Nate Begeman <natebegeman@mac.com> | 2008-04-19 04:17:09 +0000 |
commit | 8bd4afeb876fd0015bb808eb2f3de1fe709658a7 (patch) | |
tree | 362833f12587d36e36f3a338bbb2a7be316fd346 | |
parent | 532485cc6c078d9e51b517c6bbd8984deb17f0fe (diff) |
Generate code for annotation attributes.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49951 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGDecl.cpp | 22 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 51 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 5 |
3 files changed, 70 insertions, 8 deletions
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index e186bb69eb..df5882c217 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -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 diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index a5a51b19c7..da38698ab6 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -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); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index e192e9913e..d40e35e00c 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -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. |