зеркало из https://github.com/microsoft/clang-1.git
Generate code for annotation attributes.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49951 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
532485cc6c
Коммит
8bd4afeb87
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче