From a212c56e9b7533bcc2d6be90efd52ad241bf894e Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 4 May 2008 02:29:49 +0000 Subject: [PATCH] Simplify FunctionDecl::AddRedeclaration a bit by using std::swap. Fix 'swapping' of attributes to not insert null values into the DeclAttrs map. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50612 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/DeclBase.h | 1 + lib/AST/Decl.cpp | 39 +++++++++++++++++++++--------- lib/CodeGen/CodeGenFunction.cpp | 1 + lib/CodeGen/CodeGenModule.cpp | 42 +++++++++++++++++---------------- 4 files changed, 52 insertions(+), 31 deletions(-) diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 98a72ea7f0..f8ef8d41de 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -135,6 +135,7 @@ public: void addAttr(Attr *attr); const Attr *getAttrs() const; + void swapAttrs(Decl *D); template const T *getAttr() const { for (const Attr *attr = getAttrs(); attr; attr = attr->getNext()) diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index d2febb9cd3..1a7eecac32 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -341,6 +341,31 @@ const Attr *Decl::getAttrs() const { return (*DeclAttrs)[this]; } +void Decl::swapAttrs(Decl *RHS) { + bool HasLHSAttr = this->HasAttrs; + bool HasRHSAttr = RHS->HasAttrs; + + // Usually, neither decl has attrs, nothing to do. + if (!HasLHSAttr && !HasRHSAttr) return; + + // If 'this' has no attrs, swap the other way. + if (!HasLHSAttr) + return RHS->swapAttrs(this); + + // Handle the case when both decls have attrs. + if (HasRHSAttr) { + std::swap((*DeclAttrs)[this], (*DeclAttrs)[RHS]); + return; + } + + // Otherwise, LHS has an attr and RHS doesn't. + (*DeclAttrs)[RHS] = (*DeclAttrs)[this]; + (*DeclAttrs).erase(this); + this->HasAttrs = false; + RHS->HasAttrs = true; +} + + #define CASE(KIND) \ case KIND: \ static_cast(const_cast(this))->~KIND##Decl(); \ @@ -487,16 +512,12 @@ void FunctionDecl::AddRedeclaration(FunctionDecl *FD) { // Swap parameters, so that the most recent parameter names and // exact types (e.g., enum vs int) show up in the original // declaration. - ParmVarDecl **thisParamInfo = this->ParamInfo; - this->ParamInfo = FD->ParamInfo; - FD->ParamInfo = thisParamInfo; + std::swap(this->ParamInfo, FD->ParamInfo); // Swap the function body: all declarations share the same function // body, but we keep track of who actually defined that function // body by keeping the pointer to the body stored in that node. - Stmt *thisBody = this->Body; - this->Body = FD->Body; - FD->Body = thisBody; + std::swap(this->Body, FD->Body); // Swap type information: this is important because in C, later // declarations can provide slightly different types (enum vs. int, @@ -515,11 +536,7 @@ void FunctionDecl::AddRedeclaration(FunctionDecl *FD) { // Swap attributes. FD will have the union of the attributes from // all previous declarations. - if (DeclAttrs) { - Attr *thisAttr = (*DeclAttrs)[this]; - (*DeclAttrs)[this] = (*DeclAttrs)[FD]; - (*DeclAttrs)[FD] = thisAttr; - } + this->swapAttrs(FD); // If any declaration is inline, the function is inline. this->IsInline |= FD->IsInline; diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index bacb610a50..d050278406 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -153,6 +153,7 @@ void CodeGenFunction::GenerateCode(const FunctionDecl *FD) { CurFuncDecl = FD; FnRetTy = FD->getType()->getAsFunctionType()->getResultType(); + FD->getType().dump(); CurFn = cast(CGM.GetAddrOfFunctionDecl(FD, true)); assert(CurFn->isDeclaration() && "Function already has body?"); diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 306abd120b..d8b1fc327a 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -303,28 +303,30 @@ void CodeGenModule::EmitObjCMethod(const ObjCMethodDecl *OMD) { void CodeGenModule::EmitFunction(const FunctionDecl *FD) { // If this is not a prototype, emit the body. - if (FD->getBody()) { - // If the function is a static, defer code generation until later so we can - // easily omit unused statics. - if (FD->getStorageClass() == FunctionDecl::Static) { - // We need to check the Module here to see if GetAddrOfFunctionDecl() has - // already added this function to the Module because the address of the - // function's prototype was taken. If this is the case, call - // GetAddrOfFunctionDecl to insert the static FunctionDecl into the used - // GlobalDeclsMap, so that EmitStatics will generate code for it later. - // - // Example: - // static int foo(); - // int bar() { return foo(); } - // static int foo() { return 5; } - if (getModule().getFunction(FD->getName())) - GetAddrOfFunctionDecl(FD, true); - - StaticDecls.push_back(FD); - return; - } + if (!FD->isThisDeclarationADefinition()) + return; + + // If the function is a static, defer code generation until later so we can + // easily omit unused statics. + if (FD->getStorageClass() != FunctionDecl::Static) { CodeGenFunction(*this).GenerateCode(FD); + return; } + + // We need to check the Module here to see if GetAddrOfFunctionDecl() has + // already added this function to the Module because the address of the + // function's prototype was taken. If this is the case, call + // GetAddrOfFunctionDecl to insert the static FunctionDecl into the used + // GlobalDeclsMap, so that EmitStatics will generate code for it later. + // + // Example: + // static int foo(); + // int bar() { return foo(); } + // static int foo() { return 5; } + if (getModule().getFunction(FD->getName())) + GetAddrOfFunctionDecl(FD, true); + + StaticDecls.push_back(FD); } void CodeGenModule::EmitStatics() { -- 2.40.0