]> granicus.if.org Git - clang/commitdiff
Make sure the FunctionDecl's created by "#pragma weak" have correct ParmVarDecl's...
authorEli Friedman <eli.friedman@gmail.com>
Wed, 7 Sep 2011 04:05:06 +0000 (04:05 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Wed, 7 Sep 2011 04:05:06 +0000 (04:05 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139224 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Sema.h
lib/Sema/SemaDeclAttr.cpp
test/CodeGen/pragma-weak.c

index 1437469aeb8d613df3ef517d29fa971378715f3a..423f29f27885607f459155466706b74d88981528 100644 (file)
@@ -5324,7 +5324,8 @@ public:
   void ActOnPragmaVisibility(bool IsPush, const IdentifierInfo* VisType,
                              SourceLocation PragmaLoc);
 
-  NamedDecl *DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II);
+  NamedDecl *DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
+                                 SourceLocation Loc);
   void DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W);
 
   /// ActOnPragmaWeakID - Called on well formed #pragma weak ident.
index 0483552c51952dde43e24b42f7f42858a83d80ba..11198663520c7f673a6e443204e36519380ed43b 100644 (file)
@@ -3631,17 +3631,40 @@ void Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
 
 /// DeclClonePragmaWeak - clone existing decl (maybe definition),
 /// #pragma weak needs a non-definition decl and source may not have one
-NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II) {
+NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II,
+                                      SourceLocation Loc) {
   assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
   NamedDecl *NewD = 0;
   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
-    NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
-                                FD->getInnerLocStart(),
-                                FD->getLocation(), DeclarationName(II),
-                                FD->getType(), FD->getTypeSourceInfo());
-    if (FD->getQualifier()) {
-      FunctionDecl *NewFD = cast<FunctionDecl>(NewD);
+    FunctionDecl *NewFD;
+    // FIXME: Missing call to CheckFunctionDeclaration().
+    // FIXME: Mangling?
+    // FIXME: Is the qualifier info correct?
+    // FIXME: Is the DeclContext correct?
+    NewFD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
+                                 Loc, Loc, DeclarationName(II),
+                                 FD->getType(), FD->getTypeSourceInfo(),
+                                 SC_None, SC_None,
+                                 false/*isInlineSpecified*/,
+                                 FD->hasPrototype(),
+                                 false/*isConstexprSpecified*/);
+    NewD = NewFD;
+
+    if (FD->getQualifier())
       NewFD->setQualifierInfo(FD->getQualifierLoc());
+
+    // Fake up parameter variables; they are declared as if this were
+    // a typedef.
+    QualType FDTy = FD->getType();
+    if (const FunctionProtoType *FT = FDTy->getAs<FunctionProtoType>()) {
+      SmallVector<ParmVarDecl*, 16> Params;
+      for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(),
+           AE = FT->arg_type_end(); AI != AE; ++AI) {
+        ParmVarDecl *Param = BuildParmVarDeclForTypedef(NewFD, Loc, *AI);
+        Param->setScopeInfo(0, Params.size());
+        Params.push_back(Param);
+      }
+      NewFD->setParams(Params.data(), Params.size());
     }
   } else if (VarDecl *VD = dyn_cast<VarDecl>(ND)) {
     NewD = VarDecl::Create(VD->getASTContext(), VD->getDeclContext(),
@@ -3664,7 +3687,7 @@ void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
   W.setUsed(true);
   if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
     IdentifierInfo *NDId = ND->getIdentifier();
-    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
+    NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias(), W.getLocation());
     NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
                                             NDId->getName()));
     NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
index 1de60e106a95950a29ca7d4201f8098221838776..7ad2b77d8e7e3e8fd0cace5b923f5ee9d00e5618 100644 (file)
@@ -136,7 +136,7 @@ void __both3(void) {}
 void __a1(void) __attribute((noinline));
 #pragma weak a1 = __a1
 void __a1(void) {}
-// CHECK: define void @__a1()
+// CHECK: define void @__a1() {{.*}} noinline
 
 // attributes introduced BEFORE a combination of #pragma weak and alias()
 // hold...
@@ -144,13 +144,20 @@ void __a3(void) __attribute((noinline));
 #pragma weak a3 = __a3
 void a3(void) __attribute((alias("__a3")));
 void __a3(void) {}
-// CHECK: define void @__a3()
+// CHECK: define void @__a3() {{.*}} noinline
 
 #pragma weak xxx = __xxx
 __attribute((pure,noinline,const,fastcall)) void __xxx(void) { }
-// CHECK: void @__xxx()
+// CHECK: void @__xxx() {{.*}} noinline
 
-/// TODO: stuff that still doesn't work
+///////////// PR10878: Make sure we can call a weak alias
+void SHA512Pad(void *context) {}
+#pragma weak SHA384Pad = SHA512Pad
+void PR10878() { SHA384Pad(0); }
+// CHECK: call void @SHA384Pad(i8* null)
+
+
+///////////// TODO: stuff that still doesn't work
 
 // due to the fact that disparate TopLevelDecls cannot affect each other
 // (due to clang's Parser and ASTConsumer behavior, and quite reasonable)