From 65a6fe0c665ad16f068f7c5d3d584075f74aaf1f Mon Sep 17 00:00:00 2001 From: John McCall Date: Tue, 1 Mar 2016 06:27:40 +0000 Subject: [PATCH] Better comments for ExtParameterInfo. llvm-svn: 262308 --- clang/include/clang/AST/Type.h | 24 ++++++++++++++++++++++++ clang/include/clang/Sema/Sema.h | 11 +++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index d6e30e4f0688..464d85255ce3 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -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 getExtParameterInfos() const { assert(hasExtParameterInfos()); return ArrayRef(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; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 8ff47e93ce06..563eea0eb1a0 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -6982,11 +6982,14 @@ public: SavedPendingLocalImplicitInstantiations; }; + /// A helper class for building up ExtParameterInfos. class ExtParameterInfoBuilder { - SmallVector Infos; + SmallVector 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(); } };