[cfe-commits] r116413 - in /cfe/trunk: include/clang/AST/Type.h lib/AST/Type.cpp lib/Sema/SemaTemplate.cpp

Douglas Gregor dgregor at apple.com
Wed Oct 13 11:05:20 PDT 2010


Author: dgregor
Date: Wed Oct 13 13:05:20 2010
New Revision: 116413

URL: http://llvm.org/viewvc/llvm-project?rev=116413&view=rev
Log:
Introduce a bit into Type that keeps track of whether there are any
unnamed or local types within that type. This bit is cached along with
the linkage of a type, so that it can be recomputed (e.g., when we see
that a typedef has given a name to an anonymous declaration).

Use this bit when checking C++03 [temp.arg.type]p2, so that we don't
walk template argument types repeatedly.

Modified:
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=116413&r1=116412&r2=116413&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Wed Oct 13 13:05:20 2010
@@ -796,12 +796,16 @@
   /// \brief Whether this type is a variably-modified type (C99 6.7.5).
   bool VariablyModified : 1;
   
-  /// \brief Whether the linkage of this type is already known.
+  /// \brief Whether the linkage of this type along with the presence of any
+  /// local or unnamed types is already known.
   mutable bool LinkageKnown : 1;
   
   /// \brief Linkage of this type.
   mutable unsigned CachedLinkage : 2;
 
+  /// \brief Whether this type involves and local or unnamed types. 
+  mutable bool CachedLocalOrUnnamed : 1;
+  
   /// \brief FromAST - Whether this type comes from an AST file.
   mutable bool FromAST : 1;
 
@@ -813,7 +817,7 @@
 protected:
   /// \brief Compute the linkage of this type along with the presence of
   /// any local or unnamed types.
-  virtual Linkage getLinkageImpl() const;
+  virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
   
   enum { BitsRemainingInType = 19 };
 
@@ -959,6 +963,9 @@
   /// \brief Whether this type is a variably-modified type (C99 6.7.5).
   bool isVariablyModifiedType() const { return VariablyModified; }
   
+  /// \brief Whether this type is or contains a local or unnamed type.
+  bool hasUnnamedOrLocalType() const;
+  
   bool isOverloadableType() const;
 
   /// \brief Determine wither this type is a C++ elaborated-type-specifier.
@@ -1146,7 +1153,7 @@
   Kind TypeKind;
   
 protected:
-  virtual Linkage getLinkageImpl() const;
+  virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
   
 public:
   BuiltinType(Kind K)
@@ -1201,7 +1208,7 @@
   friend class ASTContext;  // ASTContext creates these.
 
 protected:
-  virtual Linkage getLinkageImpl() const;
+  virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
   
 public:
   QualType getElementType() const { return ElementType; }
@@ -1233,7 +1240,7 @@
   friend class ASTContext;  // ASTContext creates these.
 
 protected:
-  virtual Linkage getLinkageImpl() const;
+  virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
   
 public:
 
@@ -1267,7 +1274,7 @@
   friend class ASTContext;  // ASTContext creates these.
   
 protected:
-  virtual Linkage getLinkageImpl() const;
+  virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
   
 public:
 
@@ -1321,7 +1328,7 @@
     InnerRef(Referencee->isReferenceType()) {
   }
   
-  virtual Linkage getLinkageImpl() const;
+  virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
   
 public:
   bool isSpelledAsLValue() const { return SpelledAsLValue; }
@@ -1405,7 +1412,7 @@
   friend class ASTContext; // ASTContext creates these.
   
 protected:
-  virtual Linkage getLinkageImpl() const;
+  virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
   
 public:
   QualType getPointeeType() const { return PointeeType; }
@@ -1479,7 +1486,7 @@
 
   friend class ASTContext;  // ASTContext creates these.
 
-  virtual Linkage getLinkageImpl() const;
+  virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
   
 public:
   QualType getElementType() const { return ElementType; }
@@ -1782,7 +1789,7 @@
       NumElements(nElements), AltiVecSpec(altiVecSpec) {}
   friend class ASTContext;  // ASTContext creates these.
   
-  virtual Linkage getLinkageImpl() const;
+  virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
   
 public:
 
@@ -2023,7 +2030,7 @@
   friend class ASTContext;  // ASTContext creates these.
   
 protected:
-  virtual Linkage getLinkageImpl() const;
+  virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
   
 public:
   // No additional state past what FunctionType provides.
@@ -2081,7 +2088,7 @@
   friend class ASTContext;  // ASTContext creates these.
 
 protected:
-  virtual Linkage getLinkageImpl() const;
+  virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
   
 public:
   unsigned getNumArgs() const { return NumArgs; }
@@ -2323,7 +2330,7 @@
 protected:
   TagType(TypeClass TC, const TagDecl *D, QualType can);
 
-  virtual Linkage getLinkageImpl() const;
+  virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
   
 public:
   TagDecl *getDecl() const;
@@ -2991,7 +2998,7 @@
       BaseType(QualType(this_(), 0)) {}
 
 protected:
-  Linkage getLinkageImpl() const; // key function
+  std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const; // key function
   
 public:
   /// getBaseType - Gets the base type of this object type.  This is
@@ -3149,7 +3156,7 @@
   friend class ASTContext;  // ASTContext creates these.
 
 protected:
-  virtual Linkage getLinkageImpl() const;
+  virtual std::pair<Linkage, bool> getLinkageUnnamedLocalImpl() const;
   
 public:
   /// getPointeeType - Gets the type pointed to by this ObjC pointer.

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=116413&r1=116412&r2=116413&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Wed Oct 13 13:05:20 2010
@@ -1276,17 +1276,33 @@
     return CanonicalType->getLinkage();
   
   if (!LinkageKnown) {
-    CachedLinkage = getLinkageImpl();
+    std::pair<Linkage, bool> Result = getLinkageUnnamedLocalImpl();
+    CachedLinkage = Result.first;
+    CachedLocalOrUnnamed = Result.second;
     LinkageKnown = true;
   }
   
   return static_cast<clang::Linkage>(CachedLinkage);
 }
 
-Linkage Type::getLinkageImpl() const { 
+bool Type::hasUnnamedOrLocalType() const {
+  if (this != CanonicalType.getTypePtr())
+    return CanonicalType->hasUnnamedOrLocalType();
+  
+  if (!LinkageKnown) {
+    std::pair<Linkage, bool> Result = getLinkageUnnamedLocalImpl();
+    CachedLinkage = Result.first;
+    CachedLocalOrUnnamed = Result.second;
+    LinkageKnown = true;
+  }
+  
+  return CachedLocalOrUnnamed;
+}
+
+std::pair<Linkage, bool> Type::getLinkageUnnamedLocalImpl() const { 
   // C++ [basic.link]p8:
   //   Names not covered by these rules have no linkage.
-  return NoLinkage; 
+  return std::make_pair(NoLinkage, false);
 }
 
 void Type::ClearLinkageCache() {
@@ -1296,69 +1312,87 @@
     LinkageKnown = false;
 }
 
-Linkage BuiltinType::getLinkageImpl() const {
+std::pair<Linkage, bool> BuiltinType::getLinkageUnnamedLocalImpl() const {
   // C++ [basic.link]p8:
   //   A type is said to have linkage if and only if:
   //     - it is a fundamental type (3.9.1); or
-  return ExternalLinkage;
+  return std::make_pair(ExternalLinkage, false);
 }
 
-Linkage TagType::getLinkageImpl() const {
+std::pair<Linkage, bool> TagType::getLinkageUnnamedLocalImpl() const {
   // C++ [basic.link]p8:
   //     - it is a class or enumeration type that is named (or has a name for
   //       linkage purposes (7.1.3)) and the name has linkage; or
   //     -  it is a specialization of a class template (14); or
-  return getDecl()->getLinkage();
+  return std::make_pair(getDecl()->getLinkage(),
+                        getDecl()->getDeclContext()->isFunctionOrMethod() ||
+                        (!getDecl()->getIdentifier() &&
+                         !getDecl()->getTypedefForAnonDecl()));
 }
 
 // C++ [basic.link]p8:
 //   - it is a compound type (3.9.2) other than a class or enumeration, 
 //     compounded exclusively from types that have linkage; or
-Linkage ComplexType::getLinkageImpl() const {
-  return ElementType->getLinkage();
+std::pair<Linkage, bool> ComplexType::getLinkageUnnamedLocalImpl() const {
+  return std::make_pair(ElementType->getLinkage(), 
+                        ElementType->hasUnnamedOrLocalType());
 }
 
-Linkage PointerType::getLinkageImpl() const {
-  return PointeeType->getLinkage();
+std::pair<Linkage, bool> PointerType::getLinkageUnnamedLocalImpl() const {
+  return std::make_pair(PointeeType->getLinkage(), 
+                        PointeeType->hasUnnamedOrLocalType());
 }
 
-Linkage BlockPointerType::getLinkageImpl() const {
-  return PointeeType->getLinkage();
+std::pair<Linkage, bool> BlockPointerType::getLinkageUnnamedLocalImpl() const {
+  return std::make_pair(PointeeType->getLinkage(),
+                        PointeeType->hasUnnamedOrLocalType());
 }
 
-Linkage ReferenceType::getLinkageImpl() const {
-  return PointeeType->getLinkage();
+std::pair<Linkage, bool> ReferenceType::getLinkageUnnamedLocalImpl() const {
+  return std::make_pair(PointeeType->getLinkage(),
+                        PointeeType->hasUnnamedOrLocalType());
 }
 
-Linkage MemberPointerType::getLinkageImpl() const {
-  return minLinkage(Class->getLinkage(), PointeeType->getLinkage());
+std::pair<Linkage, bool> MemberPointerType::getLinkageUnnamedLocalImpl() const {
+  return std::make_pair(minLinkage(Class->getLinkage(),
+                                   PointeeType->getLinkage()),
+                        Class->hasUnnamedOrLocalType() ||
+                        PointeeType->hasUnnamedOrLocalType());
 }
 
-Linkage ArrayType::getLinkageImpl() const {
-  return ElementType->getLinkage();
+std::pair<Linkage, bool> ArrayType::getLinkageUnnamedLocalImpl() const {
+  return std::make_pair(ElementType->getLinkage(), 
+                        ElementType->hasUnnamedOrLocalType());
 }
 
-Linkage VectorType::getLinkageImpl() const {
-  return ElementType->getLinkage();
+std::pair<Linkage, bool> VectorType::getLinkageUnnamedLocalImpl() const {
+  return std::make_pair(ElementType->getLinkage(),
+                        ElementType->hasUnnamedOrLocalType());
 }
 
-Linkage FunctionNoProtoType::getLinkageImpl() const {
-  return getResultType()->getLinkage();
+std::pair<Linkage, bool> 
+FunctionNoProtoType::getLinkageUnnamedLocalImpl() const {
+  return std::make_pair(getResultType()->getLinkage(),
+                        getResultType()->hasUnnamedOrLocalType());
 }
 
-Linkage FunctionProtoType::getLinkageImpl() const {
+std::pair<Linkage, bool> FunctionProtoType::getLinkageUnnamedLocalImpl() const {
   Linkage L = getResultType()->getLinkage();
+  bool UnnamedOrLocal = getResultType()->hasUnnamedOrLocalType();
   for (arg_type_iterator A = arg_type_begin(), AEnd = arg_type_end();
-       A != AEnd; ++A)
+       A != AEnd; ++A) {
     L = minLinkage(L, (*A)->getLinkage());
-
-  return L;
+    UnnamedOrLocal = UnnamedOrLocal || (*A)->hasUnnamedOrLocalType();
+  }
+  
+  return std::make_pair(L, UnnamedOrLocal);
 }
 
-Linkage ObjCObjectType::getLinkageImpl() const {
-  return ExternalLinkage;
+std::pair<Linkage, bool> ObjCObjectType::getLinkageUnnamedLocalImpl() const {
+  return std::make_pair(ExternalLinkage, false);
 }
 
-Linkage ObjCObjectPointerType::getLinkageImpl() const {
-  return ExternalLinkage;
+std::pair<Linkage, bool> 
+ObjCObjectPointerType::getLinkageUnnamedLocalImpl() const {
+  return std::make_pair(ExternalLinkage, false);
 }

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=116413&r1=116412&r2=116413&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Oct 13 13:05:20 2010
@@ -2582,7 +2582,7 @@
   //
   // C++0x allows these, and even in C++03 we allow them as an extension with
   // a warning.
-  if (!LangOpts.CPlusPlus0x) {
+  if (!LangOpts.CPlusPlus0x && Arg->hasUnnamedOrLocalType()) {
     UnnamedLocalNoLinkageFinder Finder(*this, SR);
     (void)Finder.Visit(Context.getCanonicalType(Arg));
   }





More information about the cfe-commits mailing list