summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Sema/ParseAST.cpp6
-rw-r--r--clang/lib/Sema/Sema.h13
-rw-r--r--clang/lib/Sema/SemaDecl.cpp2
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp18
4 files changed, 31 insertions, 8 deletions
diff --git a/clang/lib/Sema/ParseAST.cpp b/clang/lib/Sema/ParseAST.cpp
index 7fa8c595ee3..a731401dcd7 100644
--- a/clang/lib/Sema/ParseAST.cpp
+++ b/clang/lib/Sema/ParseAST.cpp
@@ -68,6 +68,12 @@ void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer,
Consumer->HandleTopLevelDecl(ADecl.getAsVal<DeclGroupRef>());
};
+ // process any TopLevelDecls generated by #pragma weak
+ for (llvm::SmallVector<Decl*,2>::iterator
+ I = S.WeakTopLevelDecls().begin(),
+ E = S.WeakTopLevelDecls().end(); I != E; ++I)
+ Consumer->HandleTopLevelDecl(DeclGroupRef(*I));
+
Consumer->HandleTranslationUnit(Ctx);
if (PrintStats) {
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index e41172a0d55..dbf65782fb2 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -254,6 +254,13 @@ public:
};
llvm::DenseMap<IdentifierInfo*,WeakInfo> WeakUndeclaredIdentifiers;
+ /// WeakTopLevelDecl - Translation-unit scoped declarations generated by
+ /// #pragma weak during processing of other Decls.
+ /// I couldn't figure out a clean way to generate these in-line, so
+ /// we store them here and handle separately -- which is a hack.
+ /// It would be best to refactor this.
+ llvm::SmallVector<Decl*,2> WeakTopLevelDecl;
+
IdentifierResolver IdResolver;
/// Translation Unit Scope - useful to Objective-C actions that need
@@ -381,6 +388,9 @@ public:
llvm::SmallVector<SwitchStmt*,8> &getSwitchStack() {
return CurBlock ? CurBlock->SwitchStack : FunctionSwitchStack;
}
+
+ /// WeakTopLevelDeclDecls - access to #pragma weak-generated Decls
+ llvm::SmallVector<Decl*,2> &WeakTopLevelDecls() { return WeakTopLevelDecl; }
virtual void ActOnComment(SourceRange Comment);
@@ -2948,7 +2958,8 @@ public:
SourceLocation LParenLoc,
SourceLocation RParenLoc);
- void DeclApplyPragmaWeak(NamedDecl *D, WeakInfo &W);
+ NamedDecl *DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II);
+ void DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W);
/// ActOnPragmaWeakID - Called on well formed #pragma weak ident.
virtual void ActOnPragmaWeakID(IdentifierInfo* WeakName,
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 58df38b6457..8ee798aaf7d 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -5220,7 +5220,7 @@ void Sema::ActOnPragmaWeakAlias(IdentifierInfo* Name,
if (PrevDecl) {
if (!PrevDecl->hasAttr<AliasAttr>())
if (NamedDecl *ND = dyn_cast<NamedDecl>(PrevDecl))
- DeclApplyPragmaWeak(ND, W);
+ DeclApplyPragmaWeak(TUScope, ND, W);
} else {
(void)WeakUndeclaredIdentifiers.insert(
std::pair<IdentifierInfo*,WeakInfo>(AliasName, W));
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index a8efc2497ad..08b4910a4fd 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1820,8 +1820,9 @@ void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *Attr
/// DeclClonePragmaWeak - clone existing decl (maybe definition),
/// #pragma weak needs a non-definition decl and source may not have one
-static NamedDecl * DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II)
+NamedDecl * Sema::DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II)
{
+ assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
NamedDecl *NewD = 0;
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
NewD = FunctionDecl::Create(FD->getASTContext(), FD->getDeclContext(),
@@ -1837,8 +1838,7 @@ static NamedDecl * DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II)
/// DeclApplyPragmaWeak - A declaration (maybe definition) needs #pragma weak
/// applied to it, possibly with an alias.
-void Sema::DeclApplyPragmaWeak(NamedDecl *ND, WeakInfo &W) {
- assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
+void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
if (!W.getUsed()) { // only do this once
W.setUsed(true);
if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
@@ -1846,7 +1846,13 @@ void Sema::DeclApplyPragmaWeak(NamedDecl *ND, WeakInfo &W) {
NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
NewD->addAttr(::new (Context) AliasAttr(NDId->getName()));
NewD->addAttr(::new (Context) WeakAttr());
- ND->getDeclContext()->addDecl(NewD);
+ WeakTopLevelDecl.push_back(NewD);
+ // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
+ // to insert Decl at TU scope, sorry.
+ DeclContext *SavedContext = CurContext;
+ CurContext = Context.getTranslationUnitDecl();
+ PushOnScopeChains(NewD, S);
+ CurContext = SavedContext;
} else { // just add weak to existing
ND->addAttr(::new (Context) WeakAttr());
}
@@ -1862,8 +1868,8 @@ void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
if (ND->hasLinkage()) {
WeakInfo W = WeakUndeclaredIdentifiers.lookup(ND->getIdentifier());
if (W != WeakInfo()) {
- // Declaration referenced by #pragma weak before it was declared
- DeclApplyPragmaWeak(ND, W);
+ // Identifier referenced by #pragma weak before it was declared
+ DeclApplyPragmaWeak(S, ND, W);
WeakUndeclaredIdentifiers[ND->getIdentifier()] = W;
}
}
OpenPOWER on IntegriCloud