]> granicus.if.org Git - clang/commitdiff
Better comments for ExtParameterInfo.
authorJohn McCall <rjmccall@apple.com>
Tue, 1 Mar 2016 06:27:40 +0000 (06:27 +0000)
committerJohn McCall <rjmccall@apple.com>
Tue, 1 Mar 2016 06:27:40 +0000 (06:27 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@262308 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Type.h
include/clang/Sema/Sema.h

index d6e30e4f06881797a98655a6ff604a02df85b61f..464d85255ce3c9e45fb66b60c258e4059d7da147 100644 (file)
@@ -3040,6 +3040,25 @@ public:
 /// type.
 class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
 public:
+  /// Interesting information about a specific parameter that can't simply
+  /// be reflected in parameter's type.
+  ///
+  /// It makes sense to model language features this way when there's some
+  /// sort of parameter-specific override (such as an attribute) that
+  /// affects how the function is called.  For example, the ARC ns_consumed
+  /// attribute changes whether a parameter is passed at +0 (the default)
+  /// or +1 (ns_consumed).  This must be reflected in the function type,
+  /// but isn't really a change to the parameter type.
+  ///
+  /// One serious disadvantage of modelling language features this way is
+  /// that they generally do not work with language features that attempt
+  /// to destructure types.  For example, template argument deduction will
+  /// not be able to match a parameter declared as
+  ///   T (*)(U)
+  /// against an argument of type
+  ///   void (*)(__attribute__((ns_consumed)) id)
+  /// because the substitution of T=void, U=id into the former will
+  /// not produce the latter.
   class ExtParameterInfo {
     enum {
       IsConsumed      = 0x01,
@@ -3349,12 +3368,17 @@ public:
     return exception_begin() + NumExceptions;
   }
 
+  /// Is there any interesting extra information for any of the parameters
+  /// of this function type?
   bool hasExtParameterInfos() const { return HasExtParameterInfos; }
   ArrayRef<ExtParameterInfo> getExtParameterInfos() const {
     assert(hasExtParameterInfos());
     return ArrayRef<ExtParameterInfo>(getExtParameterInfosBuffer(),
                                       getNumParams());
   }
+  /// Return a pointer to the beginning of the array of extra parameter
+  /// information, if present, or else null if none of the parameters
+  /// carry it.  This is equivalent to getExtProtoInfo().ExtParameterInfos.
   const ExtParameterInfo *getExtParameterInfosOrNull() const {
     if (!hasExtParameterInfos())
       return nullptr;
index 8ff47e93ce06356f109354cf96c47daaab7a808f..563eea0eb1a010872984b016c29db44d88d17f49 100644 (file)
@@ -6982,11 +6982,14 @@ public:
     SavedPendingLocalImplicitInstantiations;
   };
 
+  /// A helper class for building up ExtParameterInfos.
   class ExtParameterInfoBuilder {
-    SmallVector<FunctionProtoType::ExtParameterInfo, 4> Infos;
+    SmallVector<FunctionProtoType::ExtParameterInfo, 16> Infos;
     bool HasInteresting = false;
 
   public:
+    /// Set the ExtParameterInfo for the parameter at the given index,
+    /// 
     void set(unsigned index, FunctionProtoType::ExtParameterInfo info) {
       assert(Infos.size() <= index);
       Infos.resize(index);
@@ -6996,9 +6999,13 @@ public:
         HasInteresting = (info != FunctionProtoType::ExtParameterInfo());
     }
 
+    /// Return a pointer (suitable for setting in an ExtProtoInfo) to the
+    /// ExtParameterInfo array we've built up.
     const FunctionProtoType::ExtParameterInfo *
     getPointerOrNull(unsigned numParams) {
-      return (HasInteresting ? Infos.data() : nullptr);
+      if (!HasInteresting) return nullptr;
+      Infos.resize(numParams);
+      return Infos.data();
     }
   };