Bug #:
Submitted by:
Reviewed by:
carbon.h looking good! Only 1 warning left...no parse errors!
This fixes 3 bugs...
- A couple tricky bugs with type canonicalization. Nested typedef's weren't being
handled properly. For example, the following didn't work:
typdef int __darwin_pid_t;
typedef __darwin_pid_t pid_t;
int getpgid(pid_t);
int getpgid(int);
- The storage class wasn't being preserved. As a result, Sema was complaining
about the following:
extern char *foo;
char *foo;
- various built-ins weren't registered...resulting in spurious warnings.
llvm-svn: 39357
diff --git a/clang/AST/SemaDecl.cpp b/clang/AST/SemaDecl.cpp
index e1848c4..0e5e658 100644
--- a/clang/AST/SemaDecl.cpp
+++ b/clang/AST/SemaDecl.cpp
@@ -96,7 +96,6 @@
Context.Target.DiagnoseNonPortability(IdLoc,
diag::port_target_builtin_use);
}
-
// If this is a builtin on this (or all) targets, create the decl.
if (unsigned BuiltinID = II->getBuiltinID())
return LazilyCreateBuiltin(II, BuiltinID, S);
@@ -172,7 +171,8 @@
// This is not right, but it's a start. If 'Old' is a function prototype with
// the same type as 'New', silently allow this. FIXME: We should link up decl
// objects here.
- if (Old->getBody() == 0 && Old->getType() == New->getType()) {
+ if (Old->getBody() == 0 &&
+ Old->getCanonicalType() == New->getCanonicalType()) {
return New;
}
@@ -197,12 +197,17 @@
Diag(OldD->getLocation(), diag::err_previous_definition);
return New;
}
-
- // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
- // TODO: This is totally simplistic. It should handle merging functions
- // together etc, merging extern int X; int X; ...
- Diag(New->getLocation(), diag::err_redefinition, New->getName());
- Diag(Old->getLocation(), diag::err_previous_definition);
+ // Verify the types match.
+ if (Old->getCanonicalType() != New->getCanonicalType()) {
+ Diag(New->getLocation(), diag::err_redefinition, New->getName());
+ Diag(Old->getLocation(), diag::err_previous_definition);
+ return New;
+ }
+ // We've verified the types match, now check if Old is "extern".
+ if (Old->getStorageClass() != ObjectDecl::Extern) {
+ Diag(New->getLocation(), diag::err_redefinition, New->getName());
+ Diag(Old->getLocation(), diag::err_previous_definition);
+ }
return New;
}
@@ -254,8 +259,19 @@
} else {
TypeRef R = GetTypeForDeclarator(D, S);
if (R.isNull()) return 0;
- VarDecl *NewVD = new VarDecl(D.getIdentifierLoc(), II, R);
+ ObjectDecl::StorageClass S;
+ switch (D.getDeclSpec().getStorageClassSpec()) {
+ default: assert(0 && "Unknown storage class!");
+ case 0: S = ObjectDecl::None;
+ case DeclSpec::SCS_extern: S = ObjectDecl::Extern; break;
+ case DeclSpec::SCS_static: S = ObjectDecl::Static; break;
+ // The following 2 should never be seen in this context.
+ case DeclSpec::SCS_auto: S = ObjectDecl::Auto; break;
+ case DeclSpec::SCS_register: S = ObjectDecl::Register; break;
+ }
+ VarDecl *NewVD = new VarDecl(D.getIdentifierLoc(), II, R, S);
+
// Merge the decl with the existing one if appropriate.
if (PrevDecl) {
NewVD = MergeVarDecl(NewVD, PrevDecl);
@@ -294,9 +310,11 @@
}
+ // FIXME: Handle storage class (auto, register). No declarator?
VarDecl *New = new VarDecl(PI.IdentLoc, II,
- TypeRef::getFromOpaquePtr(PI.TypeInfo));
-
+ TypeRef::getFromOpaquePtr(PI.TypeInfo),
+ ObjectDecl::None);
+
// If this has an identifier, add it to the scope stack.
if (II) {
New->setNext(II->getFETokenInfo<Decl>());