diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2008-12-26 00:52:02 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2008-12-26 00:52:02 +0000 |
commit | 2f402708e62f89fb875442802e3d3f20fc909d33 (patch) | |
tree | 2fcfe0150f9173b7238cbb09e3fd3224629d91e5 /lib/Sema/SemaDecl.cpp | |
parent | 7f7bb72fd0fcfc315245e811debb507f1f55456b (diff) |
Add full dllimport / dllexport support: both sema checks and codegen.
Patch by Ilya Okonsky
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61437 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 902101d617..bb0dd4d07c 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -509,6 +509,7 @@ static void MergeAttributes(Decl *New, Decl *Old) { attr = attr->getNext(); if (!DeclHasAttr(New, tmp)) { + tmp->setInherited(true); New->addAttr(tmp); } else { tmp->setNext(0); @@ -1207,9 +1208,6 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl, D.getDeclSpec().getSourceRange().getBegin()); } - // Handle attributes. - ProcessDeclAttributes(NewFD, D); - // Set the lexical context. If the declarator has a C++ // scope specifier, the lexical context will be different // from the semantic context. @@ -1386,6 +1384,9 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl, PrevDecl = 0; } } + // Handle attributes. We need to have merged decls when handling attributes + // (for example to check for conflicts, etc). + ProcessDeclAttributes(NewFD, D); New = NewFD; if (getLangOptions().CPlusPlus) { @@ -2410,7 +2411,7 @@ Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclTy *D) { } PushDeclContext(FnBodyScope, FD); - + // Check the validity of our function parameters CheckParmsForFunctionDef(FD); @@ -2422,6 +2423,25 @@ Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclTy *D) { PushOnScopeChains(Param, FnBodyScope); } + // Checking attributes of current function definition + // dllimport attribute. + if (FD->getAttr<DLLImportAttr>() && (!FD->getAttr<DLLExportAttr>())) { + // dllimport attribute cannot be applied to definition. + if (!(FD->getAttr<DLLImportAttr>())->isInherited()) { + Diag(FD->getLocation(), + diag::err_attribute_can_be_applied_only_to_symbol_declaration) + << "dllimport"; + FD->setInvalidDecl(); + return FD; + } else { + // If a symbol previously declared dllimport is later defined, the + // attribute is ignored in subsequent references, and a warning is + // emitted. + Diag(FD->getLocation(), + diag::warn_redeclaration_without_attribute_prev_attribute_ignored) + << FD->getNameAsCString() << "dllimport"; + } + } return FD; } |