diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGCXX.cpp | 9 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExprConstant.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 44 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 78 |
6 files changed, 68 insertions, 69 deletions
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index f4eae6678f3..4c2faf0a607 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/lib/CodeGen/CGCXX.cpp @@ -109,7 +109,7 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE) { const llvm::Type *Ty = CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), FPT->isVariadic()); - llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, Ty); + llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty); llvm::Value *This; @@ -204,8 +204,8 @@ CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D, getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false); const char *Name = getMangledCXXCtorName(D, Type); - - return cast<llvm::Function>(GetOrCreateLLVMFunction(Name, FTy, D)); + return cast<llvm::Function>( + GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); } const char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D, @@ -245,7 +245,8 @@ CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D, getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false); const char *Name = getMangledCXXDtorName(D, Type); - return cast<llvm::Function>(GetOrCreateLLVMFunction(Name, FTy, D)); + return cast<llvm::Function>( + GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(D, Type))); } const char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D, diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 15f1e1d4318..b6efcffdfc4 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -400,7 +400,7 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) { if (const CleanupAttr *CA = D.getAttr<CleanupAttr>()) { const FunctionDecl *FD = CA->getFunctionDecl(); - llvm::Constant* F = CGM.GetAddrOfFunction(FD); + llvm::Constant* F = CGM.GetAddrOfFunction(GlobalDecl(FD)); assert(F && "Could not find function!"); CleanupScope scope(*this); diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 74d736490a2..8ff2080efa3 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -673,7 +673,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { LV.SetGlobalObjCRef(LV, true); return LV; } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(E->getDecl())) { - return LValue::MakeAddr(CGM.GetAddrOfFunction(FD), + return LValue::MakeAddr(CGM.GetAddrOfFunction(GlobalDecl(FD)), E->getType().getCVRQualifiers(), getContext().getObjCGCAttrKind(E->getType())); } diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 36a9eabcb9c..e814dfc6153 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -406,7 +406,7 @@ public: case Expr::QualifiedDeclRefExprClass: { NamedDecl *Decl = cast<DeclRefExpr>(E)->getDecl(); if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl)) - return CGM.GetAddrOfFunction(FD); + return CGM.GetAddrOfFunction(GlobalDecl(FD)); if (const VarDecl* VD = dyn_cast<VarDecl>(Decl)) { // We can never refer to a variable with local storage. if (!VD->hasLocalStorage()) { diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 6e4a67b917b..706a97354e4 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -513,7 +513,7 @@ bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) { return VD->getStorageClass() == VarDecl::Static; } -void CodeGenModule::EmitGlobal(const GlobalDecl &GD) { +void CodeGenModule::EmitGlobal(GlobalDecl GD) { const ValueDecl *Global = GD.getDecl(); // If this is an alias definition (which otherwise looks like a declaration) @@ -561,13 +561,13 @@ void CodeGenModule::EmitGlobal(const GlobalDecl &GD) { EmitGlobalDefinition(GD); } -void CodeGenModule::EmitGlobalDefinition(const GlobalDecl &GD) { +void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) { const ValueDecl *D = GD.getDecl(); if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(D)) EmitCXXConstructor(CD, GD.getCtorType()); - else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) - EmitGlobalFunctionDefinition(FD); + else if (isa<FunctionDecl>(D)) + EmitGlobalFunctionDefinition(GD); else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) EmitGlobalVarDefinition(VD); else { @@ -584,7 +584,7 @@ void CodeGenModule::EmitGlobalDefinition(const GlobalDecl &GD) { /// to set the attributes on the function when it is first created. llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName, const llvm::Type *Ty, - const FunctionDecl *D) { + GlobalDecl D) { // Lookup the entry, lazily creating it if necessary. llvm::GlobalValue *&Entry = GlobalDeclMap[MangledName]; if (Entry) { @@ -606,15 +606,12 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName, // list, and remove it from DeferredDecls (since we don't need it anymore). DeferredDeclsToEmit.push_back(DDI->second); DeferredDecls.erase(DDI); - } else if (D && D->isThisDeclarationADefinition() && MayDeferGeneration(D)) { + } else if (const FunctionDecl *FD = cast_or_null<FunctionDecl>(D.getDecl())) { // If this the first reference to a C++ inline function in a class, queue up // the deferred function body for emission. These are not seen as // top-level declarations. - // FIXME: Make this work for ctor/dtors. We need to pass down a full - // GlobalDecl instead of just a FunctionDecl. - if (!isa<CXXConstructorDecl>(D) && - !isa<CXXDestructorDecl>(D)) - DeferredDeclsToEmit.push_back(GlobalDecl(D)); + if (FD->isThisDeclarationADefinition() && MayDeferGeneration(FD)) + DeferredDeclsToEmit.push_back(D); } // This function doesn't have a complete type (for example, the return @@ -630,8 +627,8 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName, llvm::Function::ExternalLinkage, "", &getModule()); F->setName(MangledName); - if (D && ShouldSetAttributes) - SetFunctionAttributes(D, F); + if (D.getDecl() && ShouldSetAttributes) + SetFunctionAttributes(cast<FunctionDecl>(D.getDecl()), F); Entry = F; return F; } @@ -639,12 +636,12 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(const char *MangledName, /// GetAddrOfFunction - Return the address of the given function. If Ty is /// non-null, then this function will use the specified type if it has to /// create it (this occurs when we see a definition of the function). -llvm::Constant *CodeGenModule::GetAddrOfFunction(const FunctionDecl *D, +llvm::Constant *CodeGenModule::GetAddrOfFunction(GlobalDecl GD, const llvm::Type *Ty) { // If there was no specific requested type, just convert it now. if (!Ty) - Ty = getTypes().ConvertType(D->getType()); - return GetOrCreateLLVMFunction(getMangledName(D), Ty, D); + Ty = getTypes().ConvertType(GD.getDecl()->getType()); + return GetOrCreateLLVMFunction(getMangledName(GD.getDecl()), Ty, GD); } /// CreateRuntimeFunction - Create a new runtime function with the specified @@ -654,7 +651,7 @@ CodeGenModule::CreateRuntimeFunction(const llvm::FunctionType *FTy, const char *Name) { // Convert Name to be a uniqued string from the IdentifierInfo table. Name = getContext().Idents.get(Name).getName(); - return GetOrCreateLLVMFunction(Name, FTy, 0); + return GetOrCreateLLVMFunction(Name, FTy, GlobalDecl()); } /// GetOrCreateLLVMGlobal - If the specified mangled name is not in the module, @@ -924,9 +921,10 @@ static void ReplaceUsesOfNonProtoTypeWithRealFunction(llvm::GlobalValue *Old, } -void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) { +void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) { const llvm::FunctionType *Ty; - + const FunctionDecl *D = cast<FunctionDecl>(GD.getDecl()); + if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { bool isVariadic = D->getType()->getAsFunctionProtoType()->isVariadic(); @@ -948,7 +946,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) { } // Get or create the prototype for the function. - llvm::Constant *Entry = GetAddrOfFunction(D, Ty); + llvm::Constant *Entry = GetAddrOfFunction(GD, Ty); // Strip off a bitcast if we got one back. if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Entry)) { @@ -973,7 +971,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(const FunctionDecl *D) { // (e.g. "int f(int x)"). Start by making a new function of the // correct type, RAUW, then steal the name. GlobalDeclMap.erase(getMangledName(D)); - llvm::Function *NewFn = cast<llvm::Function>(GetAddrOfFunction(D, Ty)); + llvm::Function *NewFn = cast<llvm::Function>(GetAddrOfFunction(GD, Ty)); NewFn->takeName(OldFn); // If this is an implementation of a function without a prototype, try to @@ -1024,7 +1022,7 @@ void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) { // if a deferred decl. llvm::Constant *Aliasee; if (isa<llvm::FunctionType>(DeclTy)) - Aliasee = GetOrCreateLLVMFunction(AliaseeName, DeclTy, 0); + Aliasee = GetOrCreateLLVMFunction(AliaseeName, DeclTy, GlobalDecl()); else Aliasee = GetOrCreateLLVMGlobal(AliaseeName, llvm::PointerType::getUnqual(DeclTy), 0); @@ -1105,7 +1103,7 @@ llvm::Value *CodeGenModule::getBuiltinLibFunction(unsigned BuiltinID) { // Unique the name through the identifier table. Name = getContext().Idents.get(Name).getName(); // FIXME: param attributes for sext/zext etc. - return GetOrCreateLLVMFunction(Name, Ty, 0); + return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl()); } llvm::Function *CodeGenModule::getIntrinsic(unsigned IID,const llvm::Type **Tys, diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 3db311243c3..5c780e755b2 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -65,6 +65,38 @@ namespace CodeGen { class CGDebugInfo; class CGObjCRuntime; +/// GlobalDecl - represents a global declaration. This can either be a +/// CXXConstructorDecl and the constructor type (Base, Complete). +/// a CXXDestructorDecl and the destructor type (Base, Complete) or +// a regular VarDecl or a FunctionDecl. +class GlobalDecl { + llvm::PointerIntPair<const ValueDecl*, 2> Value; + +public: + GlobalDecl() {} + + explicit GlobalDecl(const ValueDecl *VD) : Value(VD, 0) { + assert(!isa<CXXConstructorDecl>(VD) && "Use other ctor with ctor decls!"); + assert(!isa<CXXDestructorDecl>(VD) && "Use other ctor with dtor decls!"); + } + GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) + : Value(D, Type) {} + GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) + : Value(D, Type) {} + + const ValueDecl *getDecl() const { return Value.getPointer(); } + + CXXCtorType getCtorType() const { + assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!"); + return static_cast<CXXCtorType>(Value.getInt()); + } + + CXXDtorType getDtorType() const { + assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!"); + return static_cast<CXXDtorType>(Value.getInt()); + } +}; + /// CodeGenModule - This class organizes the cross-function state that is used /// while generating LLVM code. class CodeGenModule : public BlockModule { @@ -109,38 +141,6 @@ class CodeGenModule : public BlockModule { /// has one). llvm::StringSet<> MangledNames; - /// GlobalDecl - represents a global declaration. This can either be a - /// CXXConstructorDecl and the constructor type (Base, Complete). - /// a CXXDestructorDecl and the destructor type (Base, Complete) or - // a regular VarDecl or a FunctionDecl. - class GlobalDecl { - llvm::PointerIntPair<const ValueDecl*, 2> Value; - - public: - GlobalDecl() {} - - explicit GlobalDecl(const ValueDecl *VD) : Value(VD, 0) { - assert(!isa<CXXConstructorDecl>(VD) && "Use other ctor with ctor decls!"); - assert(!isa<CXXDestructorDecl>(VD) && "Use other ctor with dtor decls!"); - } - GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) - : Value(D, Type) {} - GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) - : Value(D, Type) {} - - const ValueDecl *getDecl() const { return Value.getPointer(); } - - CXXCtorType getCtorType() const { - assert(isa<CXXConstructorDecl>(getDecl()) && "Decl is not a ctor!"); - return static_cast<CXXCtorType>(Value.getInt()); - } - - CXXDtorType getDtorType() const { - assert(isa<CXXDestructorDecl>(getDecl()) && "Decl is not a dtor!"); - return static_cast<CXXDtorType>(Value.getInt()); - } - }; - /// DeferredDecls - This contains all the decls which have definitions but /// which are deferred for emission and therefore should only be output if /// they are actually used. If a decl is in this, then it is known to have @@ -220,7 +220,7 @@ public: /// GetAddrOfFunction - Return the address of the given function. If Ty is /// non-null, then this function will use the specified type if it has to /// create it. - llvm::Constant *GetAddrOfFunction(const FunctionDecl *D, + llvm::Constant *GetAddrOfFunction(GlobalDecl GD, const llvm::Type *Ty = 0); /// GetStringForStringLiteral - Return the appropriate bytes for a string @@ -383,7 +383,7 @@ private: llvm::Constant *GetOrCreateLLVMFunction(const char *MangledName, const llvm::Type *Ty, - const FunctionDecl *D); + GlobalDecl D); llvm::Constant *GetOrCreateLLVMGlobal(const char *MangledName, const llvm::PointerType *PTy, const VarDecl *D); @@ -406,11 +406,11 @@ private: /// EmitGlobal - Emit code for a singal global function or var decl. Forward /// declarations are emitted lazily. - void EmitGlobal(const GlobalDecl& D); + void EmitGlobal(GlobalDecl D); - void EmitGlobalDefinition(const GlobalDecl& D); + void EmitGlobalDefinition(GlobalDecl D); - void EmitGlobalFunctionDefinition(const FunctionDecl *D); + void EmitGlobalFunctionDefinition(GlobalDecl GD); void EmitGlobalVarDefinition(const VarDecl *D); void EmitAliasDefinition(const ValueDecl *D); void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D); @@ -437,8 +437,8 @@ private: void EmitCXXDestructor(const CXXDestructorDecl *D, CXXDtorType Type); // FIXME: Hardcoding priority here is gross. - void AddGlobalCtor(llvm::Function * Ctor, int Priority=65535); - void AddGlobalDtor(llvm::Function * Dtor, int Priority=65535); + void AddGlobalCtor(llvm::Function *Ctor, int Priority=65535); + void AddGlobalDtor(llvm::Function *Dtor, int Priority=65535); /// EmitCtorList - Generates a global array of functions and priorities using /// the given list and name. This array will have appending linkage and is |